Штучные Примитивы и Эквивалентность - PullRequest
15 голосов
/ 07 января 2010

Итак, мне задали этот вопрос сегодня.

Integer a = 3;
Integer b = 2;
Integer c = 5;
Integer d = a + b;
System.out.println(c == d);

Что распечатает эта программа? Это возвращает истину. Я ответил, что он всегда будет печатать ложь из-за того, как я понимал auto (и auto un) бокс. У меня сложилось впечатление, что назначение Integer a = 3 создаст новое Integer (3), так что == будет оценивать ссылку, а не примитивное значение.

Может кто-нибудь объяснить это?

Ответы [ 4 ]

20 голосов
/ 07 января 2010

Кэшированные значения в диапазоне от -128 до 127. Бокс использует Integer.valueOf метод, который использует кеш. Значения вне диапазона не кэшируются и всегда создаются как новый экземпляр. Поскольку ваши значения попадают в кешированный диапазон, значения равны с помощью оператора ==.

Цитата из спецификации языка Java:

Если значение p в боксе равно true, false, байт, символ в диапазоне \ u0000 до \ 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

11 голосов
/ 07 января 2010

Вот что на самом деле происходит:

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.

5 голосов
/ 07 января 2010

Это потому, что некоторые из (автоматически упакованных) целых чисел кэшируются, поэтому вы фактически сравниваете одну и ту же ссылку - этот пост содержит более подробные примеры и объяснения.

4 голосов
/ 07 января 2010

Кэширование тоже происходит вне автобокса, учтите это:

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

Так что я думаю, что обычно вы хотите держаться подальше от '==' при сравнении объектов

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...