Как Object.hashCode()
и _2 _ работать в бэк-энде? identityHashCode()
возвращает ссылку на объект? hashCode()
зависит от содержания или адреса объекта?
В чем разница между hashCode()
и identityHashCode()
?
Как Object.hashCode()
и _2 _ работать в бэк-энде? identityHashCode()
возвращает ссылку на объект? hashCode()
зависит от содержания или адреса объекта?
В чем разница между hashCode()
и identityHashCode()
?
Как Object.hashCode () и System.identityHashCode () работают в серверной части?
Предполагая, что он не был переопределен, метод Object.hashCode()
просто вызывает System.identityHashCode(this)
.
Точное поведение System.identityHashCode(Object)
зависит от реализации JVM. (Фактическая реализация на последних JVM Hotspot довольно умна, но я отвлекся.)
identityHashCode()
возвращает ссылку на объект?
Нет. Он возвращает int
, а int
не может содержать ссылку.
Это целое число, возвращаемое identityHashCode
, может быть связано с (а) машинным адресом объекта или не может быть 1. Значение, возвращаемое identityHashCode()
, гарантированно не изменится в течение всего времени существования объекта. Это означает, что если GC перемещает объект (после вызова identityHashCode()
), он не может использовать новый адрес объекта в качестве хэш-кода идентификации.
Зависит ли hashCode () от
?
оператора? ==
объекта, как работать в бэкэнде.
В этом нет смысла. В Java нет операторов ? ==
или ?==
.
В чем разница между hashCode () и identityHashCode ()?
Частично это объяснено выше. Другие отличия включают:
Метод hashcode()
не является конечным методом экземпляра и должен быть переопределен в любом классе, где переопределяется equals(Object)
. Напротив, identityHashCode(Object)
является static
методом и поэтому не может быть отменен.
Метод identityHashCode(Object)
дает вам идентификатор объекта, который может (теоретически) использоваться для других целей, кроме хеширования и хеш-таблиц. (К сожалению, это не уникальный идентификатор, но он гарантированно никогда не изменится в течение всего времени существования объекта.)
1 - Для JVM текущего поколения это вообще не связано с адресом памяти. См. Ответ @ bestsss.
identityHashCode()
работает так (и на данный момент он не имеет ничего общего с адресом, особенно, поскольку адреса имеют длину 64 бита, выровнены нормально, поэтому 61 ):
Проверяет, есть ли уже сгенерированный, если да, возвращает. Вы можете предположить, что в заголовке объекта есть место для этого int
;
В противном случае: генерирует случайное число (алгоритм Marsaglia shift-xor). Каждый собственный поток имеет собственное семя, поэтому общей информации нет. CAS поле identityHashCode
в заголовке объекта для обновления вновь сгенерированного числа. В случае успеха CAS возвращает значение. В противном случае поле уже содержит сгенерированный identityHashCode
.
Вы можете увидеть остальные ответы о переопределении хэш-кода.
Итог: если в JavaDoc по-прежнему что-то говорится об адресах и identityHashCode
, кто-то должен его обновить.
Это в значительной степени зависит от реализации. Единственная гарантия, которую вы получаете, это
Насколько это разумно практично, метод
hashCode
, определенный классомObject
, действительно возвращает отдельные целые числа для отдельных объектов. (Обычно это реализуется путем преобразования внутреннего адреса объекта в целое число, но этот метод реализации не требуется для языка программирования Java TM.)
(Из Java 1.6 JavaDoc)
Теоретически это означает, что значения могут быть определены произвольно и даже равны нулю для каждого объекта. На практике это, вероятно, что-то производное от адреса объекта. Конечно, с этим нужно быть осторожным. JVM может перемещать объекты, если считает это хорошей идеей во время сборки мусора, поэтому это не будет «просто» адресом памяти. Он может быть получен из глобального счетчика или хэша исходного местоположения объекта, или из генератора случайных чисел и т. Д.
Object.hashCode()
является реализацией hashCode()
по умолчанию и часто переопределяется производными классами, чтобы соответствовать правилам для _3 _ / _ 4_. System.identityHashCode()
предоставляет способ получить значение, которое Object.hashCode()
вернет для этого объекта, даже если он содержит переопределение для этого метода. Это позволяет создавать контейнеры, работающие с семантикой идентичности, поскольку ==
и System.identityHashCode()
обрабатывают каждый объект уникально.
- person templatetypedef; 08.02.2011
identityHashCode
общедоступный статический int identityHashCode (объект x)
Возвращает тот же хэш-код для данного объекта, который был бы возвращен методом по умолчанию hashCode (), независимо от того, переопределяет ли класс данного объекта hashCode (). Хэш-код для нулевой ссылки равен нулю.
См. [Java документы]
Поэтому, если кто-то переопределил метод hashCode()
в своем классе, но по-прежнему хочет значение по умолчанию hashCode()
, которое было бы возвращено Object hashCode()
, используйте System.identityHashCode()
Итак, hashCode()
внутренне вызывает System.identityHashCode()
до тех пор, пока вы не переопределяете его в своем классе, если вы переопределите hashCode (), он вызовет вашу реализацию.
Выше дано много ответов, просто нужно добавить несколько баллов.
Когда мы говорим obj.hashCode()
, содержимое объекта obj учитывается, с другой стороны, в System.identityHashCode(obj)
содержимое не принимается во внимание, таким образом, identityHashCode
для двух разных String
, int
(с одинаковым значением) будут разными, но Hashcode
будет одинаковым.
В случае String
для получения identityHashCode
пул строк играет важную роль, например
Object s1 = "abcd";
Object s2 = new String("abcd");
Object s3 = "abcd";
System.out.println("identityHashCode : " + System.identityHashCode(s1) + " HashCode : " + s1.hashCode());
System.out.println("identityHashCode : " + System.identityHashCode(s2) + " HashCode : " + s2.hashCode());
System.out.println("identityHashCode : " + System.identityHashCode(s3) + " HashCode : " + s3.hashCode());
//output:
identityHashCode : 2018699554 HashCode : 2987074
identityHashCode : 1311053135 HashCode : 2987074
identityHashCode : 2018699554 HashCode : 2987074
здесь s1
и s3
указывают на одну и ту же ссылку, поэтому identityHashCode
для s1 and s3
всегда одно и то же, а s2
будет другим.
То же самое и для int
, IntegerCache
играет важную роль для получения identityHashCode
Object s1 = 5;
Object s2 = new Integer(5);
Object s3 = 5;
System.out.println("identityHashCode : " + System.identityHashCode(s1) + " HashCode : " + s1.hashCode());
System.out.println("identityHashCode : " + System.identityHashCode(s2) + " HashCode : " + s2.hashCode());
System.out.println("identityHashCode : " + System.identityHashCode(s3) + " HashCode : " + s3.hashCode());
//Output
identityHashCode : 2018699554 HashCode : 5
identityHashCode : 1311053135 HashCode : 5
identityHashCode : 2018699554 HashCode : 5