为什么对象调用 toString() 会影响对象头的输出?我正在使用 jol 包
Why does the object call toString() affect the output of the object header? I am using the jol package
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()
您的空 class class L
使用继承自 class Object
的默认 toString()
。
默认 toString()
调用 hashCode()
.
正如您已经看到的,hashCode()
似乎也影响了 object 的 header。
所以,本质上,问题可以重述为"Why does calling hashCode()
alter the header of my object?"
正如其他人已经在评论中指出的那样,发生这种情况是因为在您使用的特定 JVM 实现中,object 的 hashCode 是在第一次调用 hashCode()
时计算的,然后它被缓存在 header 中,这样后续对 hashCode()
的调用就可以 return 缓存的值,而不必再次 re-compute 它。
除了性能,这样做还有一个更重要的原因。
根据您使用的 JVM 计算哈希码的方式,计算中可能涉及随机性,或者可能存在 ever-incrementing 数字种子,因此可能是后续尝试重现哈希码object 的计算将无法生成与第一次计算完全相同的值。这意味着第一次计算必须确定 hashcode 值将永远是什么。
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()
您的空 class class L
使用继承自 class Object
的默认 toString()
。
默认 toString()
调用 hashCode()
.
正如您已经看到的,hashCode()
似乎也影响了 object 的 header。
所以,本质上,问题可以重述为"Why does calling hashCode()
alter the header of my object?"
正如其他人已经在评论中指出的那样,发生这种情况是因为在您使用的特定 JVM 实现中,object 的 hashCode 是在第一次调用 hashCode()
时计算的,然后它被缓存在 header 中,这样后续对 hashCode()
的调用就可以 return 缓存的值,而不必再次 re-compute 它。
除了性能,这样做还有一个更重要的原因。
根据您使用的 JVM 计算哈希码的方式,计算中可能涉及随机性,或者可能存在 ever-incrementing 数字种子,因此可能是后续尝试重现哈希码object 的计算将无法生成与第一次计算完全相同的值。这意味着第一次计算必须确定 hashcode 值将永远是什么。