Указывает ли Object.toString или Object.hashCode адрес памяти объекта

Часто утверждается, что реализация Object.hashCode() (реализация по умолчанию для всех объектов) дает адрес памяти объекта. Это утверждение часто связано с объяснением специфического результата, созданного Object.to String().

См. здесь для примера.

Это, безусловно, не случай для любых JVM/JRE, о которых я знаю. Не в последнюю очередь потому, что адреса, как правило, 64 бит. Но также сборщики мусора перемещают объекты, поэтому адрес меняется. Я видел утверждения, что это может быть исходный адрес памяти объекта. Но так как многие объекты будут иметь аналогичные адреса, это будет плохой выбор для хэш-кода.

Существуют или когда-либо были широко используемые JVM/JRE, для которых он был (начальным) адресом памяти объекта.

Я знаю, что JavaDoc для класса Object предполагает, что hashCode для реализации может быть адресом памяти. Но я подозреваю, что это очень устаревшее выражение, которое никогда не обновлялось.

Действительно, текущий JVM для Oracle не использует адрес памяти (но может быть настроен для этого):

qaru.site/info/8748/...

Идея о том, что хэш-код является адресом памяти, является историческим артефактом:

qaru.site/info/5960/...

Мой вопрос в том, является ли (и который) любой широко используемый JVM использовал адрес памяти в качестве своей (по умолчанию) реализации.

Ответ 1

Поскольку хэш-код по умолчанию для объекта не обязательно должен быть уникальным, возврат всего адреса не требуется. Реализация может захватить группу битов из адреса - скажем, биты с 3 по 35 в 64-битной системе или XOR между верхними 32 битами и младшими 32 битами или просто нижние 32 бита.

Но так как многие объекты будут иметь аналогичные адреса [из-за сборки мусора], это будет плохой выбор для хэш-кода.

Хэш-коды, которые численно близки друг к другу, в порядке. Даже небольшое количество идентичных хэш-кодов не создавало бы проблемы, потому что для решения любых связей используется равенство. Ситуации, когда используется реализация хеш-кода по умолчанию, обычно ограничены, поскольку ожидается, что объекты, которые используются в качестве ключей в контейнерах на основе хэша, обеспечивают "хорошие" реализации метода hashCode.

Oracle говорит, что по умолчанию реализация их JVM использует внутренний адрес объекта, что бы это ни значило, для вычисления его hashCode. Однако другим реализациям JVM не требуется делать то же самое:

Вот кавычки из документации Oracle:

Насколько это разумно практично, метод hashCode, определенный классом Object, возвращает разные целые числа для разных объектов. (Обычно это выполняется путем преобразования внутреннего адреса объекта в целое число, но этот способ реализации не требуется языком программирования Java ™.)

Здесь вы можете найти фактическую реализацию алгоритма здесь. Найдите функцию get_next_hash для получения подробной информации. Похоже, что вычисление хэша на основе адреса выполняется с простым преобразованием:

value = intptr_t(obj) ;