Object.hashCode()算法

Roa*_*oam 13 java pseudocode hashcode

我正在寻找Object.hashCode()的算法.

此代码在Object.java中是本机代码.

这是因为

(a)代码在汇编中 - 从来没有在Java或任何其他HLL中

要么

(b)根本没有披露

在任何一种情况下,我都希望得到"如何计算hashCode()的算法(伪代码或一些详细解释)" - 它的计算中的参数和计算本身是什么?

请注意:这是 我正在寻找ObjecthashCode() -不是像StringhashMap/table那样的.

// ================================================ ==========================

新的Java文档 - JDK 8现在说

"The value returned by hashCode() is the object's hash code, which is the object's memory address in hexadecimal." 
Run Code Online (Sandbox Code Playgroud)

nku*_*har 11

本机hashCode方法的实现取决于JVM.默认情况下在HotSpot中它返回随机数,你可以在源代码中检查它(函数get_next_hash)


Pet*_*rey 8

尽管使用了Javadoc,但算法只能使用地址作为输入.这意味着即使新对象在eden空间中使用相同的地址,它们也不会具有相同的hashCode.

它可能正在使用许多算法而不是全部使用该地址.

注意:hashCode()是31位.

顺便说一下你可以Unsafe.putInt(object, 1, value)在Hotspot上设置它.

Set<Integer> ints = new LinkedHashSet<>();
int negative = 0, nonneg = 0;
for (int i = 0; i < 100; i++) {
    System.gc();
    for (int j = 0; j < 100; j++) {
        int h = new Object().hashCode();
        ints.add(h);
        if (h < 0) negative++;
        else nonneg++;
    }
}
System.out.println("unique: " + ints.size() + " negative: " + negative + " non-neg: " + nonneg);
Run Code Online (Sandbox Code Playgroud)

版画

unique: 10000 negative: 0 non-neg: 10000
Run Code Online (Sandbox Code Playgroud)

使用不安全

Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
Unsafe unsafe = (Unsafe) theUnsafe.get(null);

Object o = new Object();
System.out.println("From header " + Integer.toHexString(unsafe.getInt(o, 1L)));
// sets the hashCode lazily
System.out.println("o.hashCode()  " + Integer.toHexString(o.hashCode()));
// it's here now.
System.out.println("after hashCode() From header " + Integer.toHexString(unsafe.getInt(o, 1L)));
unsafe.putInt(o, 1L, 0x12345678);
System.out.println("after change o.hashCode()  " + Integer.toHexString(o.hashCode()));
Run Code Online (Sandbox Code Playgroud)

版画

From header 0
o.hashCode()  2260e277
after hashCode() From header 2260e277
after change o.hashCode()  12345678
Run Code Online (Sandbox Code Playgroud)


Jer*_*man 0

这是因为它依赖于未暴露给 Java 代码的低级细节。标准库的一些基本部分(如java.lang.Object)必须用本机代码实现。

顺便说一句,您至少可以找到一篇有趣的文章,其中更详细地介绍了 HotSpot 实现。