Следующий код печатает "true, true, false, true". Разве это не должно быть "правда, правда, правда, правда"?

Integer i = 127;
Integer j = 127;
System.out.println(i == j);
System.out.println(i.equals(j));

Integer i1 = 128;
Integer j1 = 128;
System.out.println(i1 == j1);
System.out.println(i1.equals(j1));

Я не понимаю, почему его не печатать "true, true, true, true". пожалуйста, дайте ответ?

Ответ 1

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

Причина, по которой первые два экземпляра равны, заключается в том, что вы создали Integers, используя autoboxing (вместо вызова new Integer(127)), а Java Спецификация языка §5.1.7 требует, чтобы Integers между -128 и 127 кэшировался.

Реализации могут кэшировать больше значений, чем это необходимо, но не требуются; видимо, JVM, который вы используете, не кэширует 128. Это относится к Sun Java 6.

Ответ 2

просто чтобы добавить ко всем другим правильным ответам, посмотрите исходный код, чтобы полностью понять, что говорят @mmyers

  584       /**
  585        * Returns an {@code Integer} instance representing the specified
  586        * {@code int} value.  If a new {@code Integer} instance is not
  587        * required, this method should generally be used in preference to
  588        * the constructor {@link #Integer(int)}, as this method is likely
  589        * to yield significantly better space and time performance by
  590        * caching frequently requested values.
  591        *
  592        * @param  i an {@code int} value.
  593        * @return an {@code Integer} instance representing {@code i}.
  594        * @since  1.5
  595        */
  596       public static Integer valueOf(int i) {
  597           final int offset = 128;
  598           if (i >= -128 && i <= 127) { // must cache
  599               return IntegerCache.cache[i + offset];
  600           }
  601           return new Integer(i);
  602       }

Ответ 3

Целое число - это класс. Если вы введете новый Integer(), вы создадите новый объект. Итак, i, j, i1 и j1 - все разные объекты. Если вы используете ==, то оно истинно только для одного и того же объекта. Для целых чисел, меньших 128, JVM всегда использует один и тот же объект, поэтому выводит true.

Ответ 4

Нет, он не должен:

Integer i1 = 128;
Integer j1 = 128;

Автообъект вызывает создание двух различных объектов Integer в реализации Java, которые вы используете.

Если целочисленные значения находились в диапазоне от -128 до 127, тогда JLS заявляет, что будет использоваться тот же объект Integer; см. JLS 1.5.7. Однако JLS делает не требование, чтобы i1 и i2 должны иметь разные значения вне этого диапазона. В самом деле, следующее обсуждение в JLS говорит об этом:

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

Для других значений эта формулировка запрещает любые предположения о идентичности вложенных значений в части программиста. Это позволило бы (но не требовать) совместного использования некоторых или всех этих ссылок.

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