Java 为什么对象调用toString()会影响对象头的输出?我正在使用jol软件包

Java 为什么对象调用toString()会影响对象头的输出?我正在使用jol软件包,java,object,jol,Java,Object,Jol,L的代码非常简单 public class L { } 取消注释,再次运行代码将导致不同的结果,或者两个完全不同的结果。我想知道这个结果的原因是什么? 不仅调用toString()会影响结果,而且对对象调用其他方法也会影响结果,例如hashCode() 您的空类类L使用从类对象继承的默认toString() 默认的toString()调用hashCode() 正如您已经看到的,hashCode()似乎也会影响对象的头 因此,本质上,这个问题可以重新表述为“为什么调用hashCode()会改

L的代码非常简单

public class L {
}

取消注释,再次运行代码将导致不同的结果,或者两个完全不同的结果。我想知道这个结果的原因是什么? 不仅调用toString()会影响结果,而且对对象调用其他方法也会影响结果,例如hashCode()


您的空类
类L
使用从
类对象继承的默认
toString()

默认的
toString()
调用
hashCode()

正如您已经看到的,
hashCode()
似乎也会影响对象的头

因此,本质上,这个问题可以重新表述为“为什么调用
hashCode()
会改变我的对象的头?”

正如其他人在评论中已经指出的那样,之所以会发生这种情况,是因为在您使用的特定JVM实现中,在第一次调用
hashCode()
时会计算对象的hashCode,然后将其缓存在头中,以便后续对
hashCode()
的调用可以只返回缓存的值,无需重新计算

除了性能,这样做可能还有更重要的原因


根据您正在使用的JVM如何计算哈希代码,计算中可能会涉及到随机性,或者可能会有一个不断递增的数字种子,因此可能是后续尝试再现对象的哈希代码将无法生成与第一次计算完全相同的值。这意味着第一次计算必须确定hashcode值将永远是什么。

这实际上是一个有趣的问题,我可能会有一个提示(我将查找引用):调用hashcode()将使用布局中的一个字段,因此,多次调用的结果都是一样的。我发现我读到的文章是:@JohannesKuhn-重点是在网站上有一个可以回答的独立问题。请注意,hashcode的部分出现在值中:3f 99 bd 52。您看到的与@JohannesKuhn:如果您调用
hashCode
首次在对象上(使用默认的hashCode实现),它将该hashCode(实例标识hashCode)存储在对象头中。
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());
    }
}