System.identityHashCode() может возвращать один и тот же hashCode после того, как объект GC'ed

Предположим, что System.identityHashCode(object1)==123 и object1 являются сборщиком мусора. Возможно ли, что вновь созданный object2 может иметь тот же код идентификатора, что и object1, полученный до того, как он был GC'ed?


person Chriss    schedule 17.12.2015    source источник
comment
Да, это вполне возможно.   -  person fge    schedule 17.12.2015
comment
Возможно даже, что два объекта, которые существуют одновременно, имеют один и тот же identityHashCode.   -  person Mark Rotteveel    schedule 17.12.2015
comment
Обратите внимание, что поведение System.identityHashCode() такое же, как и у Object.hashCode() — оно просто игнорирует любые переопределения hashCode() в подклассах.   -  person Andreas Fester    schedule 17.12.2015


Ответы (2)


Возможно ли, что новый созданный объект2 может иметь тот же код идентификатора, что и объект1, полученный до того, как он был GC'ed?

Да, это так.

Хэш-код идентификации (обычно) получается из адреса объекта, когда метод вызывается для объекта впервые. Если GC перемещает object1 после вычисления хэш-кода, новый объект (object2) может быть выделен по адресу, ранее использовавшемуся для object1. Тогда вы можете получить object1 и object2 с одинаковым хэш-кодом... несмотря на то, что object1 и object2 являются разными объектами (согласно ==).

Это хэш-коды... а не уникальные идентификаторы объектов.


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

Личность уникальна. Идентификационные хэш-коды не являются. Как сказано в Object javadoc :

"Насколько это целесообразно, метод hashCode, определенный классом Object, действительно возвращает разные целые числа для разных объектов."

Это далеко не гарантия уникальности.

А потом:

"(Обычно это реализуется путем преобразования внутреннего адреса объекта в целое число, но этот метод реализации не требуется языком программирования Java™.)"

Он имеет в виду адрес объекта при первом вызове hashCode(). В контракте для метода hashCode() указано, что значение хэш-кода не может измениться. Идентификационный хэш-код... в действительности... запоминается как часть объекта, так что объект может быть перемещен сборщиком мусора.

person Stephen C    schedule 17.12.2015
comment
Есть ли официальная документация по этому поводу? Мое понимание identity заключается в том, что объекты внутри JVM уникальны в данный момент времени. @Mark Rotteveel говорит в своем комментарии, что объект identiyHashCode cof 2 может быть одним и тем же во время выполнения, это противоречит -> хэш-код идентичности - это адрес, по которому был выделен объект. - person Chriss; 17.12.2015
comment
Но идентификационный хэш-код — это не адрес, по которому был выделен объект — утверждение состоит в том, что он (обычно) получен из адреса.... См. также пояснения на stackoverflow.com/questions/25111131/ - person Thomas Kläger; 17.12.2015
comment
это противоречит -› хэш-код идентификатора является адресом, на котором был размещен объект - Нет, это не так. (Даже игнорируя полученную из точки.) Объект может быть перемещен GC, а затем новый объект может быть выделен по исходному адресу первого объекта. Если это произойдет, оба объекта могут получить один и тот же хэш-код идентификации. - person Stephen C; 29.04.2016

Можно по определению.

identityHashCode это int. В Java всего 232 различных целых чисел.
Вы можете легко написать программу, которая создает более 232 объектов.

person apangin    schedule 21.12.2015