Разъяснения относительно сравнения целых чисел?
class Demo{
public static void main(String[] args) {
Integer i = Integer.valueOf(127);
Integer j = Integer.valueOf(127);
System.out.println(i==j);
Integer k = Integer.valueOf(128);
Integer l = Integer.valueOf(128);
System.out.println(k==l);
}
}
Первое выражение print печатает true, а второе - false. Почему? Пожалуйста, объясните подробно.
3 ответа
Это потому, что целочисленное кеширование.
Из спецификации языка Java 5.1.7
If the value p being boxed is true, false, a byte, or a char in the range
\u0000 to \u007f, or an int or short number between -128 and 127 (inclusive),
then let r1 and r2 be the results of any two boxing conversions of p.
It is always the case that r1 == r2.
В идеале, бокс заданного примитивного значения p всегда будет давать одинаковую ссылку.
Integer i = Integer.valueOf(127);
Integer j = Integer.valueOf(127);
И то и другое i
а такжеj
указать на тот же объект. Так как значение меньше 127.
Integer k = Integer.valueOf(128);
Integer l = Integer.valueOf(128);
И то и другое k
&l
указывают наразные объекты. Так как значение больше 127.
Как вы проверяете ссылки на объекты, используя==
оператор, вы получаете разные результаты.
Обновить
Ты можешь использоватьequals()
способ получить тот же результат
System.out.println(i.equals(j));//equals() compares the values of objects not references
System.out.println(k.equals(l));//equals() compares the values of objects not references
Выход
true
true
==
Оператор проверяет фактические ссылки на объекты.equals()
проверяет значения (содержимое) объектов.
Ответ на комментарий
У тебя есть,
Integer i = Integer.valueOf(127);
Здесь новый объект создан и ссылка назначена i
Integer j = Integer.valueOf(127); //will not create new object as it already exists
Из-за целочисленного кэширования (число от -128 до 127) ранее созданная ссылка на объект присваивается j
, затем i
а также j
указать на те же объекты.
Теперь рассмотрим,
Integer p = Integer.valueOf(127); //create new object
Integer q = Integer.valueOf(126); //this also creates new object as it does not exists
Очевидно, что обе проверки с использованием ==
оператор и equals()
метод приведет false
, Так как оба разные ссылки и имеют разные вейлы.
i==j
является true
для значений между -128
а также 127
из-за целочисленного кеширования.
Если значение p в штучной упаковке является истинным, ложным, байтом или символом в диапазоне от \u0000 до \u007f, или целым или коротким числом от -128 до 127 (включительно), то пусть r1 и r2 будут результатами любые два преобразования бокса р. Это всегда тот случай, когда r1 == r2.
Integer i = Integer.valueOf(127); // new object
Integer j = Integer.valueOf(127); //cached object reference
Integer k = Integer.valueOf(128); // new object
Integer l = Integer.valueOf(128); // new object
Так i
а также j
указывают на одну и ту же ссылку из-за значения 127.
В то время как k
а также l
указывая на разницу ссылок, потому что их значение >127
Есть причина, упомянутая в документации для этого поведения:
Поведение будет желаемым, без наложения чрезмерной потери производительности, особенно на небольших устройствах. Реализации с меньшим объемом памяти могут
valueOf возвращает объект Integer. Integer - это класс-оболочка для int. Для вашего случая
Integer == Integer сравнивает фактическую ссылку на объект, где int == int будет сравнивать значения.
Как уже говорилось, значения от -128 до 127 кэшируются, поэтому для них возвращаются одни и те же объекты.
Если за пределами этого диапазона будут созданы отдельные объекты, поэтому ссылка будет другой.
Если вы хотите получить одинаковый результат для обоих случаев, вы исправите это следующим образом:
- Сделайте типы int
- Приведите типы к int или
- Используйте.equals()