Вопрос-ответ

Why is 128==128 false but 127==127 is true when comparing Integer wrappers in Java?

Почему 128==128 равно false, но 127== 127 равно true при сравнении целочисленных оболочек в Java?
class D {
public static void main(String args[]) {
Integer b2=128;
Integer b3=128;
System.out.println(b2==b3);
}
}

Вывод:

false

class D {
public static void main(String args[]) {
Integer b2=127;
Integer b3=127;
System.out.println(b2==b3);
}
}

Вывод:

true

Примечание: Числа от -128 до 127 являются true.

Переведено автоматически
Ответ 1

Когда вы компилируете числовой литерал в Java и присваиваете ему целое число (заглавное I), компилятор выдает:

Integer b2 =Integer.valueOf(127)

Эта строка кода также генерируется при использовании автоматической упаковки.

valueOf реализован таким образом, что определенные числа "объединяются", и он возвращает один и тот же экземпляр для значений меньше 128.

Из исходного кода java 1.6, строка 621:

public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}

Значение high может быть настроено на другое значение с помощью системного свойства.


-Djava.lang.Integer.IntegerCache.high=999


Если вы запустите свою программу с этим системным свойством, она выдаст true!

Очевидный вывод: никогда не полагайтесь на идентичность двух ссылок, всегда сравнивайте их с помощью .equals() метода.

Таким образом, b2.equals(b3) будет выведено true для всех логически равных значений b2, b3.

Обратите внимание, что Integer кэш используется не из соображений производительности, а скорее для соответствия JLS, раздел 5.1.7; идентификатор объекта должен быть указан для значений от -128 до 127 включительно.

Integer#valueOf(int) также документирует это поведение:


этот метод, вероятно, обеспечит значительно лучшую производительность по пространству и времени за счет кэширования часто запрашиваемых значений. Этот метод всегда будет кэшировать значения в диапазоне от -128 до 127 включительно и может кэшировать другие значения за пределами этого диапазона.


Ответ 2

Автоматическое блокирование кэшей от 128 до 127. Это указано в JLS (5.1.7).


Если значение p , помещаемое в коробку, является true, false, байтом, символом в диапазоне от \ u0000 до \ u007f , или int или коротким числом от -128 до 127, то пусть r1 и r2 являются результатами любых двух упаковочных преобразований p. Всегда бывает, что r1 == r2.


Простое правило, которое следует помнить при работе с объектами: используйте, .equals если вы хотите проверить, "равны" ли два объекта, используйте, == когда вы хотите увидеть, указывают ли они на один и тот же экземпляр.

Ответ 3

Использование примитивных типов данных, целых чисел , в обоих случаях дало бы ожидаемый результат true.

Однако, поскольку вы используете целочисленные объекты, оператор == имеет другое значение.

В контексте объектов == проверяет, ссылаются ли переменные на одну и ту же ссылку на объект.

Для сравнения значений объектов вы должны использовать метод equals(), например.

 b2.equals(b1)

который укажет, меньше ли b2, чем b1, больше или равно (подробности смотрите в API)

Ответ 4

Это связано с оптимизацией памяти в Java.


Для экономии памяти Java "повторно использует" все объекты-оболочки, значения которых попадают в следующие диапазоны:


Все логические значения (true и false)


Все байтовые значения


Все символьные значения от \u0000 до \u007f (т. е. От 0 до 127 в десятичной системе счисления)


Все короткие и целочисленные значения от -128 до 127.


java