The default implementation of hashCode() on HotSpot returns a random value and stores it in the object header. This doesn't seem to have changed in Java 8 where the hash value is calculated by a call to os::random():
static inline intptr_t get_next_hash(Thread * Self, oop obj) {
intptr_t value = 0 ;
if (hashCode == 0) {
// This form uses an unguarded global Park-Miller RNG,
// so it's possible for two threads to race and generate the same RNG.
// On MP system we'll have lots of RW access to a global, so the
// mechanism induces lots of coherency traffic.
value = os::random() ;
} else
...
I'm wondering why hashCode() constantly returns the same value, also after shutting down the JVM which I tried by executing the simple test below, restarting my machine and then running main() again.
public class SimpleTest {
public static void main(String[] args) {
Object obj = new Object();
// This calls toString() which calls hashCode() which calls os::random()
System.out.println(obj);
}
}
How can the output be the same everytime if hashCode() is actually os::random()?
java -version gives
java version "1.8.0_40"
Java(TM) SE Runtime Environment (build 1.8.0_40-b25)
Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode)
Note:
Should someone ask themselves what System.out.println(obj);, which calls obj.toString() if the object is non-null and produces something like java.lang.Object@659e0bfd, has to do with hashCode(): The part after @ is the object's hash code in hexadecimal (and is unrelated with the object's location in memory, contrary to what the documentation suggests, which has led to misunderstandings).