如果hashCode()没有被覆盖,那么对象的哈希代码是什么?

2022-08-31 12:07:34

如果hashCode()方法没有被覆盖,那么在Java中的任何对象上调用hashCode()的结果会是什么?


答案 1

在 HotSpot JVM 中,默认情况下,第一次调用非重载或随机数时生成并存储在对象标头中。随后调用或仅从标头中提取此值。默认情况下,它与对象内容或对象位置没有任何共同之处,只是随机数。此行为由 HotSpot JVM 选项控制,该选项具有以下可能的值:Object.hashCodeSystem.identityHashCodeObject.hashCodeSystem.identityHashCode-XX:hashCode=n

  • 0:使用全局随机生成器。这是 Java 7 中的默认设置。它的缺点是,来自多个线程的并发调用可能会导致争用条件,从而导致为不同的对象生成相同的哈希代码。此外,在高并发环境中,由于争用(使用来自不同 CPU 内核的相同内存区域),可能会出现延迟。
  • 5:使用一些线程局部异或移随机发生器,该生成器没有以前的缺点。这是 Java 8 中的默认设置。
  • 1:使用对象指针混合一些随机值,这些值在“停止世界”事件上更改,因此在停止世界事件(如垃圾回收)之间生成的哈希码是稳定的(用于测试/调试目的)
  • 2:始终使用(用于测试/调试目的)1
  • 3:使用自动增量编号(出于测试/调试目的,也使用全局计数器,因此可以争用和争用条件)
  • 4:如有必要,使用修剪为32位的对象指针(用于测试/调试目的)

请注意,即使您设置了 ,哈希码也不会总是指向对象地址。对象可能会在以后移动,但哈希码将保持不变。此外,对象地址分布不佳(如果您的应用程序使用的内存不多,则大多数对象将彼此靠近),因此,如果使用此选项,则最终可能会遇到不平衡的哈希表。-XX:hashCode=4


答案 2

通常,hashCode() 只是返回内存中对象的地址,如果你不覆盖它。

1

尽管合理实用,但由类 Object 定义的 hashCode 方法确实为不同的对象返回不同的整数。(这通常是通过将对象的内部地址转换为整数来实现的,但 JavaTM 编程语言不需要这种实现技术。

1http://java.sun.com/javase/6/docs/api/java/lang/Object.html#hashCode