Тест равенства Java Wrapper
public class WrapperTest {
public static void main(String[] args) {
Integer i = 100;
Integer j = 100;
if(i == j)
System.out.println("same");
else
System.out.println("not same");
}
}
Вышеприведенный код выводит результат same
при запуске, однако, если мы изменим значение i
и j
на 1000, выход изменится на not same
. Поскольку я готовлюсь к SCJP, нужно понять эту концепцию. Может кто-то объяснить это поведение. Спасибо.
Ответы
Ответ 1
В Java целые числа от -128 до 127 (включительно) обычно представлены одним и тем же экземпляром объекта Integer. Это связано с использованием внутреннего класса IntegerCache (содержащегося внутри класса Integer и используемого, например, при вызове Integer.valueOf() или во время автобоксинга):
private static class IntegerCache {
private IntegerCache(){}
static final Integer cache[] = new Integer[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Integer(i - 128);
}
}
Смотрите также: http://www.owasp.org/index.php/Java_gotchas
Ответ 2
В принципе, целые числа между -127 и 127 "кэшируются" таким образом, что при использовании этих чисел вы всегда ссылаетесь на один и тот же номер в памяти, поэтому ваш ==
работает.
Любое целое вне этого диапазона не кэшируется, поэтому ссылки не совпадают.
Ответ 3
@tunaranch - это правильно. Это также та же проблема, что и в этом Python вопросе. Суть в том, что Java хранит объект вокруг целых чисел от -128 до 127 (Python делает -5 до 256) и возвращает один и тот же объект каждый раз, когда вы его запрашиваете. Если вы запрашиваете Integer вне этого фиксированного диапазона, каждый раз он будет давать вам новый объект.
(Напомним, что ==
возвращает, являются ли два объекта фактически одинаковыми, а equals
сравнивает их содержимое.)
Изменить: здесь соответствующий абзац из Раздел 5.1.7 Спецификация языка Java:
Если значение p, помещенное в квадрат, равно true
, false
, a byte
, a char
в диапазоне \u0000
до \u007f
, или int или short номер между -128 и 127, затем пусть r1 и r2 - результаты любых двух конверсии бокса на стр. Это всегда случай, когда r1 == r2.
Обратите внимание, что это также описывает, что происходит с другими типами.
Ответ 4
Это делать с равенством и autoboxing: http://web.archive.org/web/20090220142800/http://davidflanagan.com/2004/02/equality-and-autoboxing.html
Ответ 5
Ваш код не компилируется. Это то, что я получаю:
Исключение в потоке "main" java.lang.Error: нерешенные проблемы компиляции: Тип несоответствия: невозможно преобразовать из int в Integer Тип несоответствия: невозможно преобразовать из int в Integer
at WrapperTest.main(WrapperTest.java:5)
Переменные я и j являются экземплярами объекта Integer. Не сравнивайте экземпляры объекта с помощью оператора "==", вместо этого используйте метод "equals".
Привет