Разъяснения относительно сравнения целых чисел?

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  
  1. ==Оператор проверяет фактические ссылки на объекты.
  2. 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()
Другие вопросы по тегам