Вопрос

Рассмотрим этот код:

class test {
   public static void main(String[] args) {
      test inst_test = new test();
      int i1 = 2000;
      int i2 = 2000;
      int i3 = 2;
      int i4 = 2;
      Integer Ithree = new Integer(2); // 1
      Integer Ifour = new Integer(2); // 2
      System.out.println( Ithree == Ifour );
      inst_test.method( i3 , i4 );
      inst_test.method( i1 , i2 );
   }
   public void method( Integer i , Integer eye ) {
      System.out.println(i == eye );
   }
}

Он печатает:

false
true
false

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

Следующее true а также false Попросите меня почесать голову. Почему Java рассматривает i3 а также i4 равен, но i1 а также i2 другой? Оба были завернуты в целое число, не должны оба оценить на ложь? Есть ли практическая причина этого несоответствия?

Это было полезно?

Решение

Автобоксинг примитивов в объекты (как используется в ваших вызовах для method использует кэш из небольших значений. От Спецификация языка Java Раздел 5.1.7:

Если значение p в штучной упаковке верно, false, байт, символ в диапазоне u0000 до u007f, или int или короткое число между -128 и 127, тогда пусть R1 и R2 будут результатами любых двух преобразований бокса. р. Это всегда тот случай, когда r1 == r2.

Дискуссионная часть спецификации сразу после этого тоже интересна. Примечательно JVM может кэшировать более Значения, если это захочет - вы не можете быть уверены в результатах выполнения:

Integer i1 = 129;
Integer i2 = 129;
boolean b = (i1 == i2);

Другие советы

При автобоксинге, целые числа между -128 и 127 кэшируются, и возвращается тот же объект обертки. То же самое с логическими значениями и значениями ChAR между U0000 и U007F

Это то, что вы получаете большую часть времени, однако это зависит от реализации JVM.

Это связано с тем, что бокс делает целые числа ниже определенного значения (я думаю, 128) относятся к некоторому предварительному объекту и более высокие значения для новых объектов.

Автобоксинг использует Integer.valueof (i), не новое целое число (i), чтобы построить объект целого числа класса.

Как сказали другие, ValueOf () использует кэш, в основном для эффективности пространства.

Не используйте == На эталонных типах это почти всегда ошибка.

Целое число класса содержат кэш некоторых часто используемых экземпляров. Диапазон значений, как правило, варьируется от JVM к JVM (иногда также настраивается), но в целом соответствующий код - что -то вроде:

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

(Код от Sun JDK 1.6)

Это похоже на запекание строк, поскольку он сохраняет память и позволяет тестовому равенству, используя ссылку (например, == на месте равно)

Я предполагаю, что обертка пытается минимизировать количество целочисленных объектов и создает только один объект, представляющий 2 слишком сохранение памяти.

Просто не забывайте никогда не использовать == на объектах, вы никогда не знаете, что происходит.

Автобоксинг используйте некоторый механизм кэширования. Обычно вам никогда не следует полагаться на ==, всегда используйте equals Чтобы проверить равенство.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top