jvm何时在对象头中分配哈希码值

nai*_*fei 4 java jvm

我了解到java 对象头包含hashcode,gc year,biased lock等信息.然后一个谜题来到我面前,为了明确表达我的问题.我举个例子.
这是代码:

public class Demo{
    @Override
    public int hashCode(){
        System.out.println("the hashCode method was called");
        return super.hashCode();
    }

    public static void main(String[] args){
        Demo demo = new Demo();
        System.out.println("after generate an object");
        //
        Set<Demo> set = new HashSet<Demo>();
        set.add(demo);
    }
}
Run Code Online (Sandbox Code Playgroud)

并输出:

after generate an object
the hashCode method was called
Run Code Online (Sandbox Code Playgroud)

我想当我们新建一个对象时,jvm会在对象头中设置hashcode.但是如果为了生成hashCode,它应该调用这个对象的hashCode方法. 但是根据输出似乎它没有在新的对象时调用hashCode方法.并将值添加到hashSet 中调用hashCode方法,这是预期的.

所以我的问题是:jvm什么时候在对象头中分配哈希码值?它发生在一个新的对象阶段?

  • 如是.为什么它没有调用hashcode方法,没有这个如何计算这个对象的hashcode.
  • 如果第唔......这是毫无意义的是更新哈希码对象头每次调用调用hashCode方法.

apa*_*gin 6

  • JVM不需要调用hashCode方法来初始化对象的身份hashCode。它以相反的方式工作:Object.hashCodeSystem.identityHashCode调用JVM以计算或提取先前计算的身份hashCode。
  • 没有指定JVM如何生成和存储身​​份hashCode。不同的JVM实现可能会做不同的事情。
  • HotSpot JVM在首次调用Object.hashCode或时会计算标识hashCode,System.identityHashCode并将其存储在对象标头中。后续调用仅从标头中提取先前计算的值。


dpr*_*dpr 5

我认为你混淆了hashcode和identity-hashcode.

对象的哈希码不会存储在对象头中,而是通过根据需要调用哈希码方法来计算.在您的示例中,调用哈希码是因为您要将对象添加到HashSet.

身份哈希码由JVM在创建对象时计算,并且作为对象的哈希码值的回退而服务于其中.那Object.hashcode()将返回对象的标识哈希码.在对象的生命周期内,此值不会更改.

有关详细信息,请参阅此问题.