hashCode()是如何实现的?
我的假设是它使用对象内存位置作为运行哈希函数的初始数(种子).然而,这种情况并非如此.
我也看过Hash:它在内部如何运作?但它没有回答我的问题.
是的我可以下载SDK,但在我这样做并查看代码之前,也许其他人已经了解它.
谢谢 :)
编辑: 我知道它应该被覆盖等等,所以请尽量保持主题:)
G. *_*cki 21
不不不.此主题中的所有答案都是错误的,或者至少只是部分正确.
第一种:
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
Run Code Online (Sandbox Code Playgroud)
如果你在HotSpot源代码中挖掘一下,你可能会在下面的代码片段中找到:
if (hashCode == 0) {
value = os::random();
} else {
...
Run Code Online (Sandbox Code Playgroud)
os::random() 只是Park-Miller伪随机生成器算法的实现.
就这样.没有任何内存地址的概念.虽然另外两个实现, 1并 4使用对象的内存地址,但默认的不使用它.基于对象地址
的概念Object.hashCode()在很大程度上是一个历史性的假象 - 它不再是真实的.
我知道在Object#hashCode()JavaDoc中我们可以读到:
(...)这通常通过将对象的内部地址转换为整数来实现,但Java™编程语言不需要此实现技术.
但它已经过时且具有误导性.
当然,它是特定于实现的,但通常对象的哈希码将被延迟计算并存储在对象头中。奇怪的事情是使用标头来保持它们很小,同时允许复杂的锁定算法。
在 OpenJDK/Oracle JVM 中,计算初始哈希码的常用方法是基于第一次请求时的内存地址。对象在内存中移动,因此每次都使用地址并不是一个好的选择。哈希码不是实际的地址 - 它通常是 8 的倍数,这不适合直接在哈希表中使用,特别是具有 2 的幂大小。请注意,身份哈希码不是唯一的。
HotSpot 具有构建时间选项,可以始终使用零或使用安全随机数生成器 (SRNG) 进行测试。
| 归档时间: |
|
| 查看次数: |
3846 次 |
| 最近记录: |