Следующий код выводит "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));

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

4   10  

4 ответа:

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

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

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

Просто чтобы добавить ко всем другим правильным ответам, взгляните на исходный код , чтобы полностью понять, что говорит @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       }

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

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

Integer i1 = 128;
Integer j1 = 128;

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

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

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

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

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