Ответ 1
Нативная реализация метода hashCode
зависит от JVM
. По умолчанию в HotSpot возвращается случайное число, вы можете проверить его в исходном коде (функция get_next_hash
)
Я ищу алгоритм Object.hashCode().
Этот код является родным в Object.java.
Это потому, что
(a) код находится в сборке - никогда не был на Java или любой другой HLL вообще
или
(b) он просто не раскрывается
?
В любом случае я ищу, чтобы овладеть алгоритмом (псевдокодом или некоторым подробным объяснением) "как hashCode()" - каковы параметры, входящие в его расчета и самого расчета?
Обратите внимание: это hashCode() Объект, который я ищу - не похоже на String или hashMap/table.
//============================================= =============================
новые документы Java - jdk 8 теперь говорит
"The value returned by hashCode() is the object hash code, which is the object memory address in hexadecimal."
Нативная реализация метода hashCode
зависит от JVM
. По умолчанию в HotSpot возвращается случайное число, вы можете проверить его в исходном коде (функция get_next_hash
)
Несмотря на Javadoc, algo может использовать адрес только как вход. Это означает, что, хотя новые объекты используют один и тот же адрес в пространстве eden, у них не будет одинакового hashCode.
Существует несколько алгот, которые он может использовать, и не все используют адрес.
Примечание: hashCode() - 31-разрядный.
BTW Вы можете установить его с помощью 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 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
hashCode
- это собственный метод, который означает, что системная библиотека называется внутренне. Это связано с тем, что hashcode внутренне попытается сгенерировать число в зависимости от местоположения памяти объекта. Этот код зависит от машины и, вероятно, написан на C.
Но если вам действительно интересно увидеть собственный код, выполните следующие действия:
http://hg.openjdk.java.net/jdk7/jdk7-gate/jdk/file/e947a98ea3c1/src/share/native/java/
Это потому, что он опирается на детали низкого уровня, которые не подвержены Java-коду. Некоторые базовые части стандартной библиотеки (например, java.lang.Object
) должны быть реализованы в собственном коде.
В стороне, вы можете найти хотя бы одну интересную статью, которая более подробно описывает реализацию HotSpot.