How do hashCode() and identityHashCode() work at the back end?
Solution 1
How do Object.hashCode() and System.identityHashCode() work at the back end?
Assuming that it hasn't been overridden, the Object.hashCode()
method simply calls System.identityHashCode(this)
.
The exact behavior of System.identityHashCode(Object)
depends on the JVM implementation. (The actual implementation on recent Hotspot JVMs is rather clever, but I digress.)
Does
identityHashCode()
return the reference of the object?
No. It returns an int
, and an int
cannot hold a reference.
That integer returned by identityHashCode
may be related to the (a) machine address for the object, or it may not be1. The value returned by identityHashCode()
is guaranteed not to change for the lifetime of the object. This means that if the GC relocates an object (after an identityHashCode()
call) then it cannot use the new object address as the identity hashcode.
Does hashCode() depend on the
?
of the object? ==
operator how to work in back end.
This doesn't make sense. There is no ? ==
or ?==
operator in Java.
What is the difference between hashCode() and identityHashCode()?
This is partly explained above. Other differences include:
The
hashcode()
method is a non-final instance method, and should be overridden in any class where theequals(Object)
is overridden. By contrast,identityHashCode(Object)
is astatic
method and therefore cannot be overridden.The
identityHashCode(Object)
method gives you a identifier for an object which can (in theory) be used for other things than hashing and hash tables. (Unfortunately, it is not a unique identifier, but it is guaranteed to never change for the lifetime of the object.)
1 - For current generation JVMs, it is not related to the memory address at all. See @bestsss's answer.
Solution 2
identityHashCode()
works like that (and as of now it has nothing do to w/ the address, esp. since the addresses are 64bits long, ok aligned, so 61):
Checks if there is already generated one, if so returns it. You can assume there is a place in the object header for that int
;
Otherwise: Generates a random number (Marsaglia shift-xor algorithm). Every native thread has its own seed, so no shared info.
CAS the identityHashCode
field in the object header to update w/ the newly generated number. If CAS succeeds, returns the value. If not, the field already contains a generated identityHashCode
.
You can see the rest of the replies about overriding hashcode.
Bottom line:
If the JavaDoc still states anything about addresses and identityHashCode
, someone needs to update it.
Solution 3
This is pretty much implementation specific. The only guarantee you get is
As much as is reasonably practical, the
hashCode
method defined by classObject
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.)
(From the Java 1.6 JavaDoc)
In theory, this means that the values could be determined arbitrarily and could even be zero for every object. In practice, it's probably something derived from the address of the object. Of course, you have to be careful about this. The JVM can relocate objects if it thinks it's a good idea during a garbage collection, so it's not going to be "just" the memory address. It could be drawn from a global counter, or a hash of the original object's location, or from a random number generator, etc.
Solution 4
Lots of answers given above, just need to add some points.
When we say obj.hashCode()
the content of the obj is considered, on the other hand
in System.identityHashCode(obj)
the content are not taken in consideration, thus identityHashCode
for two different String
, int
(with same value) will be the different but Hashcode
will be the same.
In case of String
to get identityHashCode
string pool plays important role, example
Object s1 = "abcd";
Object s2 = new String("abcd");
Object s3 = "abcd";
System.out.println("identityHashCode : " + System.identityHashCode(s1) + " HashCode : " + s1.hashCode());
System.out.println("identityHashCode : " + System.identityHashCode(s2) + " HashCode : " + s2.hashCode());
System.out.println("identityHashCode : " + System.identityHashCode(s3) + " HashCode : " + s3.hashCode());
//output:
identityHashCode : 2018699554 HashCode : 2987074
identityHashCode : 1311053135 HashCode : 2987074
identityHashCode : 2018699554 HashCode : 2987074
here s1
and s3
pointing same ref therefore identityHashCode
for s1 and s3
is always same and s2
will be different.
Same for int
also, IntegerCache
plays the important role to get the identityHashCode
Object s1 = 5;
Object s2 = new Integer(5);
Object s3 = 5;
System.out.println("identityHashCode : " + System.identityHashCode(s1) + " HashCode : " + s1.hashCode());
System.out.println("identityHashCode : " + System.identityHashCode(s2) + " HashCode : " + s2.hashCode());
System.out.println("identityHashCode : " + System.identityHashCode(s3) + " HashCode : " + s3.hashCode());
//Output
identityHashCode : 2018699554 HashCode : 5
identityHashCode : 1311053135 HashCode : 5
identityHashCode : 2018699554 HashCode : 5
Solution 5
identityHashCode
public static int identityHashCode(Object x)
Returns the same hash code for the given object as would be returned by the default method hashCode(), whether or not the given object's class overrides hashCode(). The hash code for the null reference is zero.
See [Java docs]
So if someone has overridden hashCode()
method in its class but still want the default hashCode()
value which would have been returned by Object hashCode()
then use System.identityHashCode()
So, hashCode()
internally calls System.identityHashCode()
as long as you are not overriding it in you class, if you override hashCode() it will call your implementation.
Admin
Updated on December 06, 2020Comments
-
Admin over 3 years
How do
Object.hashCode()
andSystem.identityHashCode()
work at the back end? DoesidentityHashCode()
return the reference of the object? DoeshashCode()
depend on the content or address of the object?What is the difference between
hashCode()
andidentityHashCode()
? -
Björn over 13 yearsYou're right, I must have mixed something up. I got stuck in the documentation to back my hypotesis -- but failed. ;-) deleted my answer and upvoted yours!
-
Admin over 13 yearswhat is the difference between hashCode() and identityHashCode()?
-
templatetypedef over 13 years@Himanshu-
Object.hashCode()
is the default implementation ofhashCode()
and is often overridden by derived classes to conform to the rules forequals()
/hashCode()
.System.identityHashCode()
provides a way to get the value thatObject.hashCode()
would return for that object even if it contains an override for this method. This allows you to make containers that work with identity semantics, since==
andSystem.identityHashCode()
treat each object uniquely. -
Raedwald about 8 yearsThe idea that hashCode uses the memory address is a historical artefact stackoverflow.com/questions/36236615/…
-
eis over 6 yearsThere are 5 alternatives of hash code calculation in the code. Looking at this one can see that option 5, Marsaglia shift-xor, is really currently used. Hashcode generation has been elaborated more in this blog post