hashCode()是如何用Java实现的

hashCode()是如何实现的?

我的假设是它使用对象内存位置作为运行哈希函数的初始数(种子)。 然而,这种情况并非如此。

我也看过Hash:它是如何在内部工作的? 但它没有回答我的问题。

是的我可以下载SDK,但在我这样做并查看代码之前,也许其他人已经了解它。

谢谢 :)

编辑:我知道它应该被覆盖等等,所以请尽量保持主题:)

当然它是特定于实现的,但通常对象的哈希码将被懒惰地计算并存储在对象头中。 奇怪的事情是使用标题来保持小,同时允许复杂的锁定算法。

在OpenJDK / Oracle JVM中,计算初始哈希码的常用方法是基于第一次请求时的内存地址。 对象在内存中移动,因此每次使用地址都不是一个好的选择。 哈希码不是实际地址 – 通常是8的倍数,这对于在哈希表中直接使用尤其是具有两个大小的幂而言并不是很好。 注意标识哈希码不是唯一的。

HotSpot具有构建时间选项以始终使用零或使用安全随机数生成器(SRNG)进行测试。

不不不。 此主题中的所有答案都是错误的,或者至少只是部分正确。

首先: Object.hashCode()是一个本机方法,因此它的实现完全取决于 JVM。 它可能因HotSpot和其他VM实现(如JRockit或IBM J9)而异。

如果你问:

hashCode()是如何在Java中实现的?

然后答案是 :它取决于您使用的是哪个VM。

假设您正在使用Oracle的默认JVM(即HotSpot),那么我可以告诉您HotSpot有六个hashCode()实现。 您可以使用-XX:hashCode=n标志通过命令行运行JVM来选择它,其中n可以是:

 0 – Park-Miller RNG (default) 1 – f(address, global_statement) 2 – constant 1 3 – Serial counter 4 – Object address 5 – Thread-local Xorshift 

以上是从这篇文章中复制的 。

如果你在HotSpot源代码中挖掘一下,你可能会在下面的代码片段中找到:

 if (hashCode == 0) { value = os::random(); } else { ... 

os::random()只是Park-Miller伪随机生成器算法的实现。

就这样。 没有任何内存地址的概念。 虽然另外两个实现, 14 ,使用对象的内存地址,但默认的不使用它。
Object.hashCode()基于对象地址的概念在很大程度上是一个历史性的假象 – 它不再是真的。


我知道在Object#hashCode() JavaDoc里面我们可以读到:

(…)这通常通过将对象的内部地址转换为整数来实现,但Java™编程语言不需要此实现技术。

但它已经过时且具有误导性。

hashcode()函数的实现因Object而异。 如果您想知道特定类如何实现hashcode(),您将不得不查找该类。

类Object定义的hashCode方法为不同的对象返回不同的整数。 这可以通过将对象的内部地址转换为整数来实现(但标准不要求此实现样式)。 新的类覆盖hashCode以支持哈希表(相等和hashCode),这很有趣: http : //www.javapractices.com/topic/TopicAction.do? Id = 28

我假设您正在讨论hashCodeObject实现,因为该方法可以而且应该被覆盖。

它依赖于实现。 对于Sun JDK,它基于对象的内存地址。