@erickson is more or less correct. The hashcode returned by java.lang.Object.hashCode()
does not change for the lifetime of the object.
The way this is (typically) implemented is rather clever. When an object is relocated by the garbage collector, its original hashcode has to be stored somewhere in case it is used again. The obvious way to implement this would be to add a 32 bit field to the object header to hold the hashcode. But that would add a 1 word overhead to every object, and would waste space in the most common case ... where an Object's hashCode
method is not called.
The solution is to add two flag bits to the object's flag word, and use them (roughly) as follows. The first flag is set when the hashCode
method is called. A second flag tells the hashCode
method whether to use the object's current address as the hashcode, or to use a stored value. When the GC runs and relocates an object, it tests these flags. If the first flag is set and second one is unset, the GC allocates one extra word at the end of the object and stores the original object location in that word. Then it sets the two flags. From then on, the hashCode
method gets the hashcode value from the word at the end of the object.