Что именно сравнивает Integer with == do?

ИЗМЕНИТЬ: ОК, ОК, я неправильно понял. Я не сравниваю int с Integer. Должен заметить.

В моей книге SCJP говорится:

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

Итак, вы думаете, что этот код напечатает true:

    Integer i1 = 1; //if this were int it'd be correct and behave as the book says.
    Integer i2 = new Integer(1);
    System.out.println(i1 == i2);

но он печатает false.

Кроме того, согласно моей книге, это должно печатать true:

Integer i1 = 1000; //it does print `true` with i1 = 1000, but not i1 = 1, and one of the answers explained why.
Integer i2 = 1000;
System.out.println(i1 != i2);

Неа. Это false.

Что дает?

Ответ 1

Integer i1 = 1;
Integer i2 = new Integer(1);
System.out.println(i1 == i2);

Когда вы назначаете 1 в i1, это значение помещается в бокс, создавая объект Integer. Затем сравнение сравнивает две ссылки на объекты. Ссылки неравны, поэтому сравнение не выполняется.

Integer i1 = 100;
Integer i2 = 100;
System.out.println(i1 != i2);

Поскольку они инициализируются константами времени компиляции, компилятор может и делает их стажером и делает оба объекта одинаковыми с объектом Integer.

(Обратите внимание, что я изменил значения от 1000 до 100. Как указывает @NullUserException, только маленькие целые числа интернированы.)


Вот действительно интересный тест. Посмотрите, можете ли вы это понять. Почему первая программа печатает true, а вторая - false? Используя свои знания по боксу и анализу времени компилятора, вы должны понять это:

// Prints "true".
int i1 = 1;
Integer i2 = new Integer(i1);
System.out.println(i1 == i2);

// Prints "false".
int i1 = 0;
Integer i2 = new Integer(i1);
i1 += 1;
System.out.println(i1 == i2);

Если вы это понимаете, попробуйте предсказать, что печатает эта программа:

int i1 = 0;
i1 += 1;
Integer i2 = new Integer(i1);
System.out.println(i1 == i2);

(После того, как вы догадались, запустите его и посмотрите!)

Ответ 2

Обратите внимание также, что более новые версии кэша Java Integer в диапазоне от -128 до 127 (256 значений), что означает:

Integer i1, i2;

i1 = 127;
i2 = 127;
System.out.println(i1 == i2);

i1 = 128;
i2 = 128;
System.out.println(i1 == i2);

Будет напечатан true и false. (см. раздел ideone)

Мораль: Чтобы избежать проблем, всегда используйте .equals() при сравнении двух объектов.

Вы можете полагаться на unboxing, когда вы используете == для сравнения обернутого примитива с примитивом (например: Integer с int), но если вы сравниваете два Integer с ==, которые будут не удалось объяснить причины @dan04.

Ответ 3

Вы не сравниваете примитив с оберткой. Вы сравниваете две обертки (ссылочные типы). == сравнивает идентификатор объекта, который возвращает false, потому что это разные объекты.

Ответ 4

Нет, я бы не подумал, что этот код напечатал true, и вы сами ответили, почему именно.

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

после чего вы сравнили две ссылки Integer, то есть сравнили адрес памяти i1 и i2. Вы хотели либо

Integer i1 = 1;
Integer i2 = new Integer(1);
System.out.println(i1.equals(i2));

Или

int i1 = 1;
Integer i2 = new Integer(1);
System.out.println(i1 == i2);

Ответ 5

Обратите внимание, что вы неправильно читаете выдержку, которую вы цитировали. Выдержка специально ограничивает его выражение для таких сравнений:

int k = 1;
Integer l = new Integer(1);
System.out.println(l == k);

Ответ 6

Начиная с Java 5.0, есть автоматический бокс и unboxing, что означает, что обертки могут быть неявно преобразованы в примитивы и наоборот. Однако, если вы сравниваете два объекта Integer, вы по-прежнему сравниваете две ссылки, и нет ничего, что могло бы привести к автоматическому боксу/распаковке. Если бы это было так, код, написанный на J2SE 1.4 и предыдущем, сломался.

Ответ 7

Предположим, что пусть имеет пример

Каков будет выход этого программного кода?

public class autoboxing {
public static void main(String a args) {
Integer a = new Integer(127);
Integer b = new Integer(127);
Integer c = 127;
Integer d = 127;
Integer e = new Integer(200);
Integer f = new Integer(200);
Integer g = 200;
Integer h = 200;
System.out.println((a == b) + ' " + (c =-- d) + " " + (e==f)+ " "+ (g == h));

.

Когда вы создаете объект Integer с новым оператором, он каждый раз возвращает новый объект. Когда вы сравниваете две контрольные переменные с оператором "==" , если две ссылочные переменные относятся к двум различным объектам, оператор "==" возвращает false.

Итак,

(a == b) и (e == f) выражения возвращают false. Integer класс кэширует значения от -128 до 127.

Когда вы сравниваете два объекта Integer с оператором "==" , если эти два целочисленных объекта создаются с помощью autoboxing, тогда вызывается метод value0f (int i).

ОТВЕТ: False True False False

Ниже приведена реализация этого метода

public static Integer value0f(int i) {
if (i >= IntegerCachedow && i <= IntegerCache.high)
return IntegerCache.cacheli + (-IntegerCachedow));
return new Integer(i);

Из приведенной выше реализации ниже приведены выводы

  • Если два значения объектов Integer находятся между -128 и 127, этот метод возвращает одинаковые значения. Итак (c == d) возвращает true.

  • Если два значения объектов Integer находятся за пределами диапазона от -128 до 127, этот метод возвращает разные новые объекты Integer. Итак, (g == h) возвращает false

Подробнее о методе здесь: https://stackoverflow.com/info/20897020/why-integer-class-caching-values-in-the-range-128-to-127