tags:

views:

535

answers:

5

Is the output of Object.hashCode() required to be the same on all JVM implementations for the same Object?

For example if "test".hashCode() returns 1 on 1.4, could it potentially return 2 running on 1.6. Or what if the operating systems were different, or there was a different processor architecture between instances?

+3  A: 

From the API

The general contract of hashCode is:

  • Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
  • If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
  • It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.

As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the JavaTM programming language.)

Jim Garrison
+1 for quoting proper part of api.
Thorbjørn Ravn Andersen
-1 this does not answer the question
finnw
@finnw: Yes it does; hashCode is not required to return the same value across different *runs* of the same version on the same system for the same application, never mind across different versions or different systems or different applications.
Software Monkey
+2  A: 

No, the result of hashCode() is only constant during a single execution. You should not expect the result of the function to be the same between executions, let alone between JRE versions or platforms.

Paul Lammertsma
+6  A: 

No. The output of hashCode is liable to change between JVM implementations and even between different executions of a program on the same JVM.

However, in the specific example you gave, the value of "test".hashCode() will actually be consistent because the implementation of hashCode for String objects is part of the API of String (see the Javadocs for java.lang.String and this other SO post).

Phil
(Although it will be different if you can find a 1.0 JDK. The broken definition in the API docs would actually throw exceptions if implemented.)
Tom Hawtin - tackline
It's also well defined for most collections
finnw
A: 

first of all, the result of hashCode depends heavily on the Object type and its implementation. every class including its subclasses can define its own behavior. you can rely on it following the general contract as outlined in the javadoc as well as in other answers. but the value is not required to stay the same after a VM restart. especially if it depends on the .hashCode implementations of thrid party classes.

when referring to the concrete implementation of the String class, you should not depend on the return value. if you program is executed in a different VM, it could potentially change.

if you refer solely to the Sun Vm, it could be argued that Sun will not break - even badly programmed - existing code. so "test".hashCode() will always return exactly 3556498 for any version of the Sun VM.

if you want to deliberatly shoot yourself in the foot, go ahead and depend on this. people who will need to fix your code running on the "2015 Nintendo Java VM for Hairdryer" will cry out your name at night.

Andreas Petersson
A: 

As noted, for many implementations the default behavior of hashCode() is to return the address of the object. Obviously this can be different each time the program is run. This is also consistent with the default behavior of equals(): two objects are equal only if they are the same object (where x and y are both non-null, x.equals(y) if and only if x == y).

For any classes where hashCode() and equals() are overridden, generally they are calculated in a deterministic way based on the values of some or all of the members. Thus, in practice it is likely that if an object in one run of the program can be said to be equal to an object in another run of the program, and the source code is the same (including such things as the source code for String.hashCode() if that is called by the hashCode() override), the hash codes will be the same.

It is not guaranteed, although it is hard to think of a reasonable real-world example.

Mark Lutton
@Mark: a reasonable example is where you override `hashCode()` and have the hashcode calc include the hashcode of a component object whose `hashCode()` is not overridden.
Stephen C
That would do it, but then you would not be able to allow two objects to be equal. Two "equal" objects would have different hashcodes. If you put such an object into a HashMap you would not be able to find it again.
Mark Lutton