Making enum hashcodes consistent across JVM's

Raffaello Giulietti raffaello.giulietti at gmail.com
Thu Mar 17 14:59:09 UTC 2022


Hi,

specifying a fixed hashCode() algorithm has the important drawback that 
it prevents evolution.

For example, as you note, String has a strictly specified algorithm [1] 
that was perhaps a good one in the early days of Java (around 1995) but 
has shown its deficiencies over the years. In particular, it's easy to 
construct collisions, which might impact the performance of popular and 
heavily used hash based data structures, like HashMap and HashSet, under 
some forms of cyberattack.

Unfortunately, while better String hash algorithms have been proposed, 
they cannot be adopted, as too much code out there relies on the 
specific details of String::hashCode. (Even bytecode for switches over 
String relies on that particular spec.) It's far too late now to change 
the spec, even for the better.

In retrospect and IMO, fixing String::hashCode in the spec was a 
(understandable) mistake.


More generally, client code that relies on details of any popular 
library hashCode() implementation has a dangerous dependency on such 
details and impairs evolution of the library itself (as the example with 
String shows).

To leave the door open for better implementations proposed in some 
future, it is best to avoid specifying the details of hashCode(), as 
done in Record::hashCode [2] ("Implementation Requirements"). After all, 
the general contract reads [3]: "This integer [the hash] need not remain 
consistent from one execution of an application to another execution of 
the same application."


But what is the use case you have for which you would like a firmly 
specified Enum::hashCode?


Greetings
Raffaello

----

[1] 
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html#hashCode()
[2] 
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Record.html#hashCode()
[3] 
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html#hashCode()



On 2022-03-17 13:49, dfranken.jdk at gmail.com wrote:
> Dear all,
> 
> Currently enums do not have a well-defined hashCode() implementation so
> they defer to Object.hashCode() which just uses an internal mechanism
> to determine the hashcode, likely based on the object's place in the
> heap.
> 
> This may confuse a lot of developers as other classes such as String do
> have a well-defined hashcode which is consistent across multiple JVM's.
> 
> Could it be a good idea to make enums' hashCode() method more reliably
> and predictable? For instance by using the hashcode of the name of its
> value?
> 
> For example:
> 
> class MyEnum { A, B }
> -> A.hashCode() == A.name().hashCode()
> 
> Kind regards,
> 
> Dave Franken


More information about the core-libs-dev mailing list