Исправленные примитивы и эквивалентность в штучной упаковке
Поэтому мне сегодня задали этот вопрос.
Integer a = 3;
Integer b = 2;
Integer c = 5;
Integer d = a + b;
System.out.println(c == d);
Что выйдет из этой программы? Он возвращает true. Я ответил, что он всегда будет печатать ложно из-за того, как я понял auto (и auto un) бокс. У меня создалось впечатление, что назначение Integer a = 3 создаст новый Integer (3), так что == будет оценивать ссылку, а не примитивное значение.
Кто-нибудь может это объяснить?
Ответы
Ответ 1
Вставлены в кешированные значения от -128 до 127. Бокс использует метод Integer.valueOf
, который использует кеш. Значения вне диапазона не кэшируются и всегда создаются как новый экземпляр. Поскольку ваши значения попадают в кешированный диапазон, значения равны с использованием оператора ==.
Цитата из спецификации языка Java:
Если значение p в коробке равно true, false, байт, a char в диапазоне \ u0000 to\u007f, или int или short номер между -128 и 127, затем пусть r1 и r2 - результаты любых двух конверсии бокса на стр. Это всегда случай, когда r1 == r2.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7
Ответ 2
Вот что происходит на самом деле:
Integer c = Integer.valueOf(5);
Integer d = Integer.valueOf(a.intValue() + b.intValue());
Java поддерживает кеш объектов Integer
между -128 и 127. Сравните со следующим:
Integer a = 300;
Integer b = 200;
Integer c = 500;
Integer d = a + b;
System.out.println(c == d);
Для печати false
.
Ответ 3
Это потому, что некоторые из (автоматически помеченных) Целых кешируются, поэтому вы фактически сравниваете одну и ту же ссылку - этот пост содержит более подробные примеры и объяснение.
Ответ 4
Кэширование происходит вне автобоксинга, рассмотрите это:
Integer a = 1;
Integer b = new Integer(1);
Integer c = Integer.valueOf(1);
System.out.println(a == b);
System.out.println(b == c);
System.out.println(c == a);
это напечатает:
false
false
true
Итак, я предполагаю, что в целом вы хотите избегать "==" при сравнении объектов