Подтвердить что ты не робот

Целочисленные объекты-оболочки имеют одни и те же экземпляры только в пределах значения 127?

Здесь они являются одним и тем же экземпляром:

Integer integer1 = 127;
Integer integer2 = 127;
System.out.println(integer1 == integer2);  // outputs "true"

Но здесь они разные экземпляры:

Integer integer1 = 128;
Integer integer2 = 128;
System.out.println(integer1 == integer2);  // outputs "false"

Почему объекты-оболочки имеют один и тот же экземпляр только внутри значения 127?

4b9b3361

Ответ 1

Потому что он задан спецификацией языка Java.

JLS 5.1.7 Конверсия бокса:

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

В идеале, бокс данного примитивного значения p, всегда будет давать идентичную ссылку. На практике это может оказаться невозможным с использованием существующих методов внедрения. Правила выше - прагматичный компромисс. Последнее заключительное предложение требует, чтобы определенные общие значения всегда помещались в неразличимые объекты. Реализация может кэшировать эти, лениво или нетерпеливо. Для других значений эта формулировка запрещает любые предположения о идентичности вложенных значений в части программиста. Это позволило бы (но не требовать) совместного использования некоторых или всех этих ссылок.

Это гарантирует, что в большинстве распространенных случаев поведение будет желательным, не налагая чрезмерного штрафа за производительность, особенно на небольшие устройства. Менее ограниченные памятью реализации могут, например, кэшировать все значения char и short, а также значения int и long в диапазоне от -32K до + 32K.

Ответ 2

Источник java.lang.Integer:

public static Integer valueOf(int i) {
        final int offset = 128;
        if (i >= -128 && i <= 127) { // must cache
            return IntegerCache.cache[i + offset];
        }
        return new Integer(i);
    }

Ура!

Ответ 3

Кстати, вы можете сократить свой код до

System.out.println("Integer 127 == " + ((Integer) 127 == (Integer) 127));
System.out.println("Integer 128 == " + ((Integer) 128 == (Integer) 128));

for(int i=0;i<5;i++) {
    System.out.println(
     "Integer 127 system hash code " + System.identityHashCode((Integer) 127)
     + ", Integer 128 system hash code "+System.identityHashCode((Integer) 128));
}

печатает

Integer 127 == true
Integer 128 == false
Integer 127 system hash code 1787303145, Integer 128 system hash code 202703779
Integer 127 system hash code 1787303145, Integer 128 system hash code 1584673689
Integer 127 system hash code 1787303145, Integer 128 system hash code 518500929
Integer 127 system hash code 1787303145, Integer 128 system hash code 753416466
Integer 127 system hash code 1787303145, Integer 128 system hash code 1106961350

Вы можете видеть, что 127 - это один и тот же объект каждый раз, тогда как объект для 128 отличается.

Ответ 5

В дополнение к другим ответам я хочу добавить, что == сравнивает только ссылки на объекты. Вместо этого используйте .equals():

Integer integer1=128;
Integer integer2=128;
if(integer1.equals(integer2))
  System.out.println(true);
else
  System.out.println(false);