kotlinhashcodevalue-class

Kotlin inline value class - cannot override hashCode() function


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?


Solution

  • 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.