Overriding equals in Kotlin

I’m not certain of the reason for this error, but it might be related to a deeper problem with your approach…

In Kotlin (and Java), the equals() method has a fairly tight specification.  One condition is that it must be symmetric: whenever a and b are not null, a.equals(b) must always give the same result as b.equals(a).

But your implementation fails this test, because CS("abc").equals("abc") returns true, while "abc".equals(CS("ABC")) is false.  That’s because your class knows about CharSequences such as String, but String does not know about your class.

There’s no easy way around that.  In general, it’s much safer to allow instances of a class to equal only instances of that class.  If you control both classes, then there are ways around that, but they’re quite subtle and involved.  (Perhaps the best explanation is by Martin Odersky et al.)

So most implementations of equals() tend to work along these lines:

override fun equals(other: Any?)
    = (other is ThisClass)
    && field1 == other.field1
    && field2 == other.field2
    // ...

As I said, I don’t know why the Kotlin compiler is complaining in your case.  It may be that it has spotted something of this problem, or it may be something unrelated.  But I don’t think you’re going to be able to fix your program in a way that equality checks will do what you want, so perhaps it’s best to take this as a hint to try a slightly different approach!

Leave a Comment