interesting fact about identityHashCode() method in java.lang.System Class
The following four lines of code is provides such outputs which confused me about the identityHashCode() method of System class. System.identityHashCode() method is supposed to give the default hashcode value irrespective of whether you have overridden hascode in your class. And as we know that default implementation maps the internal memory address to an integer value.
1 String s = new String(new char[]{‘j’, ‘a’,’v’,’a’});
2 String s1 = new String(new char[]{‘a’, ‘b’,’c’,’d’});
3 System.out.println(System.identityHashCode(s));
4 System.out.println(System.identityHashCode(s1));
When I created a String instance by executing line 1 it would have got some memory location allocated to it. Lets say that is “x”. Then I created another instance s1 with passing some other different array to the String constructor. So s1 would have also got some memory location allocated for it. Lets say that is “y”.
Now when I print the identity hash code by executing the line number 3 and 4 every time I run the program it gives me the same two integer values. And the order of values depends on the execution of line number 3 and 4 but not on 1 and 2 where actual allocation of memory happened. Thats strange for me 😦
8 Comments »
Leave a reply to Oni Cancel reply
-
Recent
- interesting fact about identityHashCode() method in java.lang.System Class
- Interesting inconsistency with java String pool
- did u know u can find the location of the .class file from the instance??
- Cases for Shortcomings of Single Request-Response model
- Information asymmetry
- Another bad mark on My Image in Boss’s Mind……:(
- Sharing the same connection or transaction space between derby sql and java.
- Did u know that u can shutdown someone’s machine(windows) using java????
- Utilizing JAVA’s power in Derby Database Triggers
- Dids u know that u can search across multiple columns in a database table??
- Did you know that you can compare RAW columns in a DB?
-
Links
-
Archives
- July 2008 (2)
- April 2008 (2)
- September 2007 (5)
- August 2007 (1)
- May 2007 (1)
-
Categories
-
RSS
Entries RSS
Comments RSS
It’s strange for me also.
I was playing with your piece of code when I realized that if I debug the values changes.
Somehow I got that:
————–
String str1 = new String(“abcd”);
String str2 = new String(“efgh”);
try {
long time = (long) (Math.random() * 10000.0) ;
System.out.println(“Sleeping: ” + time);
Thread.sleep(time);
} catch (InterruptedException e) {
/**/
}
System.out.println(System.identityHashCode(str1));
System.out.println(System.identityHashCode(str2));
}
———
So it seems to me that the identityHashCode is related to the elapsed time since the jvm is started and the hash is computed.
Comment by Oni | July 31, 2008 |
hi oni
But javadoc of identityHashCode() suggests that it is the default implementation of hashcode which is essentially the Object’s implementation of hashcode. That implementation is just the integer mapping of memory location and not at all related to the time jvm has been active.
Comment by deepakjha | July 31, 2008 |
Hi,
well, as far as I understand, it’s calling a native method:
public static native int identityHashCode(Object x);
But, I suppose the same as you, is calling the Object.hashCode().
I’ve not checked the impelentation of Object.hasCode(). A quick “google” give me this, somehow interesting, result:
http://erikengbrecht.blogspot.com/2008/07/systemidentityhashcode.html
Btw, I’m running on a linux 32 bits 1.6 JVM.
Did the same as me happened to you? does the value change because of time?
Comment by Oni | July 31, 2008 |
No oni for me the values didn’t change. It was coming the same for consecutive runs of your code sample.
Comment by deepakjha | August 1, 2008 |
For me the output is:
4072869
1671711
Comment by Dave | October 8, 2008 |
Think about it — it’s a memory address. Assume the JVM is a deterministic finite state machine. Each run should go through the same internal states. So each run should be assigning the same memory locations. Now if another program is also running on that JVM and the timing relationships are flexible (as would be the case for some debuggers or multi-threaded applications), then the addresses would change with the changes to the allocation order of the objects.
Comment by Jeslie | December 5, 2008 |
If lines 1-4 are indeed your entire program, then my guess is that the jvm is inlining the instantiation of the Strings (from line 1-2) into lines 3-4, which is the only place they are used. That would explain why reordering lines 3-4 has the only effect on your output.
In general be wary of making assumptions about why something is happening based on the order of statements in your source code – barring synchronization, the jvm has wide latitude to reorder and optimize the bytecode at runtime.
Comment by Scott Bale | September 8, 2009 |
Dear friends,
Here is a piece of code that more generally aims to produce a clash in which two dissimilar objects (obj1 != obj2) produce the same hashCode() result. It is interesting that on my system only 1756 instantiations are needed before a clash is found (if the hash code algorithm can be modeled by a random distribution, this is a special instance of the birthday paradox I suppose).
import java.util.Hashtable;
import java.util.Map;
public class HashcodeTest{
static class DummyObject extends Object { }
public static void reportClash(DummyObject obj1, DummyObject obj2) {
System.out.println(“obj1.hashCode() = ” + obj1.hashCode());
System.out.println(“obj2.hashCode() = ” + obj2.hashCode());
System.out.println(“(obj1 == obj2) = ” + (obj1 == obj2) + ” (!)”);
}
public static void main(String[] args) {
Map map = new Hashtable();
for (int count = 1; true; count++) {
DummyObject obj = new DummyObject();
if (map.containsKey(obj.hashCode())) {
System.out.println(
“Clash found after instantiating ” + count + ” objects.”);
reportClash(map.get(obj.hashCode()), obj);
System.exit(0);
}
map.put(obj.hashCode(), obj);
}
}
}
For me that exemplifies that hashCode() even by all practical means is useless to serve as an object identity.
Cheers,
Frank
Comment by Frank | March 6, 2011 |