Вопрос Java об автобоксинге и равенстве/идентичности объекта
public class Main {
/**
* @param args the command line arguments */
public static void main(String[] args) {
// TODO code application logic here
int a1 = 1000, a2 = 1000;
System.out.println(a1==a2);//=>true
Integer b1 = 1000, b2 = 1000;
System.out.println(b1 == b2);//=>false
Integer c1 = 100, c2 = 100;
System.out.println(c1 == c2);//=>true
}
}
Почему b1 == b2
false и c1 == c2
true?
Ответы
Ответ 1
Прочитайте этот.
Java использует пул для Integer
в диапазоне от -128 до 127.
Это означает, что если вы создаете Integer
с Integer i = 42;
и его значение находится между -128 и 128, no создается новый объект, но возвращается соответствующий из пула. Вот почему c1
действительно идентичен c2
.
(Я полагаю, вы знаете, что ==
сравнивает ссылки, а не значения, когда применяется к объектам).
Ответ 2
Правильные ответы уже даны. Но просто чтобы добавить мои два цента:
Integer b1 = 1000, b2 = 1000;
Это ужасный код. Объекты должны быть инициализированы как объекты через конструкторы или методы factory. Например.
// let java decide if a new object must be created or one is taken from the pool
Integer b1 = Integer.valueOf(1000);
или
// always use a new object
Integer b2 = new Integer(1000);
Этот код
Integer b1 = 1000, b2 = 1000;
с другой стороны, означает, что Integer был примитивным, а это не так. Фактически, что вы видите, это ярлык для
Integer b1 = Integer.valueOf(1000), b2 = Integer.valueOf(1000);
и Integer объединяет только объекты с -127 до 127, поэтому в этом случае будет создано два новых объекта. Поэтому, хотя 1000 = 1000, b1!= B2. Это главная причина, по которой я ненавижу авто-бокс.
Ответ 3
Здесь вы можете найти ответ:
Самая странная функция языка в 6-м ответе.
Изменить: извините, но не полностью ответ. Дело в том, что == сравнивает ссылки, а не значения, когда вы используете его с Integer. Но с int "==" означает equals.
Ответ 4
Потому что Integer для нескольких низких чисел, таких как перечисление, так что всегда есть один и тот же экземпляр. Но более высокие числа создают новые экземпляры Integer, а оператор == сравнивает их ссылки
Ответ 5
public static Integer valueOf(int i) {
final int offset = 128;
if (i >= -128 && i <= 127) { // must cache
return IntegerCache.cache[i + offset];
}
return new Integer(i);
}
Из-за этого вы верны в одном случае, а false в другом!
Ответ 6
Ответ, который вы хотите, здесь
Ответ 7
Если autounbing работал также при выполнении проверки равенства с помощью оператора '==', вы могли бы написать:
Long notNullSafeLong1 = new Long(11L)
Long notNullSafeLong2 = new Long(22L)
if ( notNullSafeLong1 == notNullSafeLong2) {
do suff
Для этого потребуется реализовать переопределение для ==, так что null == someLong является ложным, а специальный регистр Null == Null - true. Вместо этого мы должны использовать equal() и test для null
Long notNullSafeLong1 = new Long(11L)
Long notNullSafeLong2 = new Long(22L)
if ( (notNullSafeLong1 == null && notNullSafeLong2 == null) ||
(notNullSafeLong1 != null && notNullSafeLong2 != null &
notNullSafeLong1.equals(notNullSafeLong2)) {
do suff
Это немного более подробный, чем первый пример - если autounboxing работал для оператора '=='.