hashCode() 和 identityHashCode() 如何在后端工作?

2022-08-31 17:34:53

Object.hashCode()System.identityHashCode() 如何在后端工作?是否返回对象的引用?是否取决于对象的内容或地址?identityHashCode()hashCode()

和 有什么区别?hashCode()identityHashCode()


答案 1

Object.hashCode() 和 System.identityHashCode() 如何在后端工作?

假设它没有被覆盖,该方法只需调用 。Object.hashCode()System.identityHashCode(this)

的确切行为取决于 JVM 实现。(在最近的Hotspot JVM上的实际实现相当聪明,但我离题了。System.identityHashCode(Object)

是否返回对象的引用?identityHashCode()

不。它返回 一个 ,而 一个 不能保存引用。intint

返回的该整数可能与对象的 (a) 计算机地址相关,也可能不是1。返回的值保证在对象的生存期内不会更改。这意味着,如果 GC 重新定位对象(在调用后),则它不能使用新对象地址作为标识哈希码。identityHashCodeidentityHashCode()identityHashCode()

hashCode() 是否依赖于对象运算符如何在后端工作。?? ==

这是没有道理的。Java 中没有 或 运算符。? ==?==

hashCode() 和 identityHashCode() 之间有什么区别?

这在上文中已有部分解释。其他差异包括:

  • 该方法是非最终实例方法,应在被重写的任何类中重写。相比之下,是一种方法,因此不能被覆盖。hashcode()equals(Object)identityHashCode(Object)static

  • 该方法为您提供了对象的标识符,该标识符(理论上)可用于哈希和哈希表以外的其他事情。(不幸的是,它不是一个一的标识符,但保证它在对象的生存期内永远不会改变。identityHashCode(Object)


1 - 对于当前一代 JVM,它与内存地址完全无关。请参阅@bestsss的答案。


答案 2

identityHashCode()像这样工作(截至目前,它与地址无关,特别是因为地址是64位长,好吧,对齐,所以61):

检查是否已经生成了一个,如果是,则返回它。您可以假设在对象标头中有一个位置int;

否则:生成一个随机数(马萨利亚移位异或算法)。每个本机线程都有自己的种子,因此没有共享信息。CAS 对象标头中的字段,以更新新生成的编号。如果 CAS 成功,则返回该值。如果不是,则该字段已包含生成的 .identityHashCodeidentityHashCode

您可以看到有关覆盖哈希码的其余回复。

底线:如果 JavaDoc 仍然声明有关地址和 的任何内容,则需要有人更新它。identityHashCode