Результаты сравнения целых чисел различаются в Java
Я начинающий Java-программист и столкнулся с очень странным сценарием, как показано ниже.
public static void main(String[] args) {
Integer a = 500;
Integer b = 500;
// Comparing the values.
a <= b; // true
a >= b; // true
a == b; // false
// Reassigning the values
a = 50;
b = 50;
// Again comparing the values.
a <= b; // true
a >= b; // true
a == b; // true
}
Мой вопрос: почему результаты a == b
варьируются в зависимости от значений?
3 ответа
Ответ на этот вопрос лежит в понимании автобокса, определенного языком программирования Java.
Изменение результатов a == b
происходит потому, что любое целое число от -128 до 127 кэшируется Integer
учебный класс. Когда int
в пределах этого диапазона создается он извлекается из IntegerCache
вместо создания нового объекта Integer.
Это ошибка? Конечно, нет!
Класс Java Integer также называется классом- оболочкой, поскольку он предоставляет объект, который оборачивает int
примитивный тип данных. В Java сравнивать два объекта значения не просто. Мы должны переопределить Object.equal
метод (а также Object.hashCode
) и использовать его, чтобы определить, когда два объекта равны. С использованием ==
оператор, в этом случае мы сравниваем два адреса физических объектов. Java требует нового оператора для создания объектов, которые будут все храниться в куче JVM. Локальные переменные хранятся в стеке JVM, но содержат ссылку на объект, а не на сам объект.
В первом случае, когда мы проверяем, a == b
мы на самом деле проверяем, указывают ли обе ссылки на одно и то же место. Ответа на это НЕТ!
Но что происходит, когда a & b 50? Чтобы ответить на это, мы должны взглянуть на ниже Integer.valueOf
метод.
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
Мы используем Autoboxing
Функция Java через это Integer.valueOf
метод для сравнения a == b
, С целью оптимизации использования ресурсов, Integer
класс поддерживает кеш-память Integer
экземпляров. Таким образом, все новые запросы Integer со значением между -128 и IntegerCache.high
(настраивается) вернет идентичный объект, выделенный один раз. Поэтому, когда мы спрашиваем, является ли a == b, мы получаем истину, потому что за сценой a и b указывают на одно и то же место в памяти.
Теперь возникает другой вопрос: включает ли этот подход проблемы совместного использования экземпляров? К счастью, ответ - нет, потому что Integer был определен как неизменяемый объект, и это означает, что если вы хотите изменить его, вы должны получить новый экземпляр… захватывающий, не так ли?
Шишир
Java интернировала значения из -128
в 127
,
Вот почему вы получаете true
когда вы сравниваете два Integer
объекты в этом диапазоне с ==
,
Да. Потому что значения в диапазоне от -127 до 128 будут храниться в кеше. так что используйте равные и сравните.