Smartcast on Javaclass equality

For equality, I often write something like

class Foo(val prop : String){
    fun equals(obj : Other) = when{
         this.javaclass != other.javaclass  -> false
         other is Foo -> false //casting
         else -> prop == other.prop
     }
}

When the java-classes are the same, we know that the properties from both classes match.
Is it possible for the compiler to know this as well?
And would it therefor be possible to skip the casting?

1 Like

You messed up the conditions here :slight_smile: You should had written:

class Foo(val prop: String) {
	override fun equals(obj: Any?) = when {
		 this.javaclass !== other.javaclass -> false
		 other !is Foo -> false // now this condition could even be merged with the one above
		 else -> prop == other.prop
	}
}

As for me I prefer to implement equals() method it this way:

class Foo(val prop: String) {
	override fun equals(obj: Any?) = this === other || other is Foo && prop == other.prop
}
3 Likes

Not only that, you must exclude the middle line in equals as other is Foo is wrong and other !is Foo is also wrong when compared structurally which seems to be the case when comparing props.

It may be worth of performance reasons to cast obj to Foo if it is of type Foo for performance reasons. Comparing Foos with each other is O(n) and comparing Foos with other kinds of objects you need O(n log(n)) as the order must not match between property sets. You need further to check if the foreign object doesn’t have more props than the Foo object (the this object).