I just cannot override hashCode() function on value class. minimal example (I know that in this example there is no need to override it...)
@JvmInline
value class Identifier(val value: String){
override fun hashCode(): Int = this.value.hashCode()
}
I get error: Member with the name 'hashCode' is reserved for future releases
Edit: Is there any way to specify own hashCode() function?
CodePudding user response:
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
andhashCode
member functions ofkotlin.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. MethodstoString
andhashCode
can be overridden as usual methods fromAny
. For methodequals
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.