2017-02-23 308 views
2

我知道java 对象头包含诸如哈希码,gc年,偏向锁等信息。然后一个难题来找我,并明确表达我的问题。我举一个例子。
下面是代码:什么时候jvm分配对象头中的hashcode值

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); 
    } 
} 

和输出:

after generate an object 
the hashCode method was called 

我想,当我们新的对象JVM将设置哈希码在对象头。但是如果这为了生成hashCode,它应该调用hashCode方法这个对象。 但是根据输出,它似乎没有调用hashCode方法当新的对象。并且将值添加到hashSet hashCode方法被调用,这正如预期的那样。

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

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

回答

3
  • JVM不需要调用hashCode方法来初始化对象的标识hashCode。它反过来工作:Object.hashCodeSystem.identityHashCode调用JVM来计算或提取以前计算的标识hashCode。
  • 没有指定JVM如何生成和存储身​​份hashCode。不同的JVM实现可能会有所不同。
  • HotSpot JVM在第一次调用Object.hashCodeSystem.identityHashCode时计算身份hashCode,并将其存储在对象头中。随后的调用只是从头中提取以前计算的值。
4

我认为你是混淆哈希码和身份哈希码。

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

身份哈希码由JVM在对象创建时进行计算,并作为对象的哈希码值的后退服务等等。那就是Object.hashcode()会返回你的对象的标识哈希码。此值将在对象的生命周期中更改为而不是

查看this question了解更多详情。

相关问题