Следующий код печатает "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.