As of right now, you cannot override the equals
or hashCode
method of value classes. The language specification explicitly disallows this:
Value classes must adhere to the following limitations:
- [...]
- They must not override
equals
and hashCode
member functions of kotlin.Any
- [...]
This is because the developers of Kotlin are planning to add a strongly typed equals
method that you can override.
From the inline classes proposal:
Methods from Any
(toString
, hashCode
, equals
) can be useful for a user-defined inline classes and therefore should be customizable. Methods toString
and hashCode
can be overridden as usual methods from Any
. For method equals
we're going to introduce new operator that represents "typed" equals
to avoid boxing for inline classes:
@JvmInline
value class Identifier(val value: String){
override fun hashCode(): Int = ...
operator fun equals(other: Identifier): Boolean = ...
}
This is so that when you use ==
on value classes with a custom equals
, you don't have to box them every time as you are passing it to the Any?
parameter on the Any.equals
method. The compiler would also automatically generate an equals(Any?)
implementation from your equals(Identifier)
implementation.
But they haven't implemented this feature yet. This is why they don't let you implement hashCode
- because if you do, you would most likely also need to implement equals(Any?)
(it is rarely useful/correct to just implement hashCode
), but that means your code would break in future versions of Kotlin! In future versions, you would need to implement equals(Identifier)
, not equals(Any?)
.
So you can only wait until this feature gets added. Until then, you cannot have hashCode
and equals
that does not delegate to the wrapped value.
equals
andhashCode
member functions ofkotlin.Any
by delegating them to their only data property.” Thus, no workaround is needed. – Trussing