#java
#java
Вопрос:
Почему System.identityHashCode() возвращает разные значения для одной и той же переменной?
public class java {
public static void main(String[] args) {
1- int v=60000;
2- System.out.println(System.identityHashCode(v));
3- System.out.println(System.identityHashCode(v));
}
}
output : 1831932724
1747585824
Комментарии:
1. Не могли бы вы попробовать заменить int v = 60000; целым числом v = 60000;? какую строку вы хотите, чтобы я изменил? @turing85
2. Пожалуйста, проверьте мой ответ. Он дает полное объяснение и демонстрации, которые показывают поведение. Этот комментарий вскоре самоуничтожится.
3. Привет, System.identityHashCode(Object) возвращает тот же хэш-код для объекта, который является истинным, когда вы передаете какой-либо объект, но в вашем случае вы передаете примитивный параметр, который автоматически помещается в его класс-оболочку (все генерирует новый автоматически загруженный объект-оболочку). Поэтому, если вам нужно использовать этот метод, я бы рекомендовал вам использовать класс-оболочку вместо primitive.
Ответ №1:
Когда мы смотрим на сигнатуру System::identityHashCode
, мы видим, что она принимает Object
параметр as . Однако предоставленный код передает примитив ( int
) в качестве параметра. int
Автоматически помещается в соответствующий класс-оболочку (в данном случае: Integer
). Java по умолчанию кэширует Integer
s в определенном диапазоне, но 60_000
находится вне диапазона по умолчанию. Это означает, что код может быть переписан на:
class Ideone {
public static void main(String[] args) {
int v = 60_000;
final Integer tmp1 = v;
final Integer tmp2 = v;
System.out.println(System.identityHashCode(tmp1));
System.out.println(System.identityHashCode(tmp2));
System.out.println(tmp1 == tmp2);
}
}
Обратите внимание, что этот код, для нашего обсуждения, идентичен предоставленному коду, но теперь мы видим, что код фактически использует два экземпляра Integer
. Поведение ожидается с момента System:identityHashCode
использования Object:hashCode
и Object:hashCode
будет (почти всегда) возвращать уникальный идентификатор для каждого экземпляра.
Если мы изменим код, чтобы использовать только один Integer
экземпляр, код будет работать так, как ожидалось:
class Ideone {
public static void main(String[] args) {
final Integer tmp1 = 60_000;
System.out.println(System.identityHashCode(tmp1));
System.out.println(System.identityHashCode(tmp1));
System.out.println(tmp1 == tmp1);
}
}
Комментарии:
1. Означает ли это, что когда я пишу открытый класс java { public static void main(String[] args) { int v=60000; System.out.println(System.identityHashCode(v)); System.out.println(System.identityHashCode(v)); } } вывод:1831932724 1747585824 потому что identityHashCode() создает два объекта. один создается в строке номер 2, а другой создается в строке номер 3? @Turing85
2. Метод
System:identityHashCode
не создает объекты, объекты создаются с помощью механизма автоматической упаковки.3. Хорошо, это означает, что с помощью механизма автоматической блокировки создаются два объекта. один создается в строке номер 2, а другой создается в строке номер 3? @Turing85
4. не уверен, какие строки вы подразумеваете под строками 2 и 3. По моим подсчетам, это строки, определяющие статический метод
main
и локальную переменнуюv
. Но они создаются двумя строками, объявляющимиtmp1
andtmp2
(в моем коде) и двумя вызовами toSystem.identityHashCode(...)
(неявно, в вашем коде).5. Я отредактировал свой пост и добавил номер в строки, можете ли вы снова просмотреть сообщение и ответить на мой вопрос (в моем коде это означает, что с помощью механизма автоматической блокировки создаются два объекта. один создается в строке номер 2 , а другой — в строке номер 3 ? и в вашем коде два объекта создаются в строке объявления tmp1 и строке объявления tmp2, верно?) и я прошу прощения за беспокойство @Turing85