14

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

此代码是Object.java中的本机代码。

这是因为

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

或者

(b) 它根本没有被披露

?

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

请注意:这是 我正在寻找Object的hashCode() ——而不是像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." 
4

4 回答 4

12

本机hashCode方法实现依赖于JVM. HotSpot默认返回随机数,可以在源码中查看(函数get_next_hash

于 2013-07-31T18:04:12.620 回答
9

尽管有 Javadoc,算法只能使用地址作为输入。这意味着即使新对象在伊甸园空间中使用相同的地址,它们也不会具有相同的 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);

印刷

unique: 10000 negative: 0 non-neg: 10000

使用不安全

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()));

印刷

From header 0
o.hashCode()  2260e277
after hashCode() From header 2260e277
after change o.hashCode()  12345678
于 2013-07-31T18:02:09.050 回答
2

hashCode是本机方法,这意味着在内部调用系统库。这是因为哈希码在内部会尝试根据对象内存位置生成一个数字。此代码与机器相关,可能是用 C 编写的。

但是,如果您真的有兴趣查看本机代码,请按照以下步骤操作:

http://hg.openjdk.java.net/jdk7/jdk7-gate/jdk/file/e947a98ea3c1/src/share/native/java/

于 2013-07-31T17:59:34.593 回答
0

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

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

于 2013-07-31T17:57:31.030 回答