L的代码很简单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()); }}取消注释,再次运行代码会得到不同的结果,或者是两个完全不同的结果。我想知道造成这个结果的原因是什么?不仅调用 toString() 会影响结果,调用对象上的其他方法也会影响结果,例如 hashCode()
1 回答
holdtom
TA贡献1805条经验 获得超10个赞
您的空类class L
使用toString()
从 继承的默认值class Object
。
默认toString()
调用hashCode()
.
正如您已经看到的,hashCode()
似乎也影响对象的标头。
因此,本质上,问题可以重述为“为什么调用会hashCode()
改变我的对象的标头?”
正如其他人已经在评论中指出的那样,发生这种情况是因为在您正在使用的特定 JVM 实现中,第一次调用时会计算对象的 hashCode,然后将其缓存在标头中,以便后续hashCode()
调用hashCode()
可以只返回缓存的值,而无需再次重新计算。
除了性能之外,这样做可能还有更重要的原因。
根据您使用的 JVM 计算哈希码的方式,计算中可能存在随机性,或者可能存在不断递增的数字种子,因此后续尝试重现对象的哈希码可能无法实现生成与第一次计算完全相同的值。这意味着第一次计算必须确定之后的哈希码值。
添加回答
举报
0/150
提交
取消