L's code is very simple
public class L {
}
public class Synchronized1 {
public static void main(String[] args) {
L l=new L();
// System.out.println(l.toString());
System.out.println(ClassLayout.parseInstance(l).toPrintable());
}
}
Uncommenting, running the code again will result in different results, or two completely different results. I want to know what is the cause of this result? Not just calling toString() affects the result, but calling other methods on the object also affects the result such as hashCode()
Your empty class class L
uses the default toString()
inherited from class Object
.
The default toString()
invokes hashCode()
.
And as you have already seen, hashCode()
also seems to affect the header of the object.
So, in essence, the problem can be restated as "Why does calling hashCode()
alter the header of my object?"
As others have already pointed in the comments, this is happening because in the particular JVM implementation that you are using, the hashCode of an object is computed the first time hashCode()
is invoked, and then it is cached in the header, so that subsequent calls to hashCode()
can just return the cached value, without having to re-compute it again.
Besides performance, there may be an even more important reason for doing this.
Depending on how the JVM that you are using computes hashcodes, there may be randomness involved in the computations, or there may be an ever-incrementing number seed, so it may be that subsequent attempts to reproduce the hashcode of an object would have no means of generating the exact same value as the first computation. This means that the very first computation must determine what the hashcode value will be forever after.