Сравнение упакованных длинных значений 127 и 128
Я хочу сравнить два долго значения объектов с помощью if
условиях. Когда эти значения менее 128 на if
условие работает правильно, но когда они больше или равно 128 сопоставление терпит неудачу.
пример:
Long num1 = 127;
Long num2 = 127;
if (num1 == num2) {
// Works ok
}
сравнение на коде выше работает правильно, но не в коде ниже:
Long num1 = 128;
Long num2 = 128;
if (num1 == num2) {
// Does NOT work
}
Почему есть проблема в сравнении долго переменные со значениями больше 127? Если переменные типы данных изменены на долго примитивов, то сравнения работают для всех случаев.
4 ответа:
TL; DR
Java кэширует целочисленные коробочные экземпляры из
-128
до127
. Так как вы используете==
чтобы сравнить ссылки на объекты вместо значений, будут совпадать только кэшированные объекты. Эфир работает сlong
распакованные примитивные значения или использовать.equals()
сравнитьLong
объекты.текст
почему существует проблема в сравнении длинной переменной со значением больше 127? Если данные тип вышеуказанной переменной примитивен (длинный), затем код работает для всех значений.
Java кэширует целочисленные экземпляры объектов из диапазона от -128 до 127. Тот сказал:
- если вы установите в N длинных переменных значение
127
( cached), один и тот же экземпляр объекта будет указан всеми ссылками. (N переменных, 1 экземпляр)- если вы установите в N длинных переменных значение
128
(не кэшированный), у вас будет экземпляр объекта, на который указывает каждая ссылка. (N переменных, N экземпляров)вот почему:
Long val1 = 127L; Long val2 = 127L; System.out.println(val1 == val2); Long val3 = 128L; Long val4 = 128L; System.out.println(val3 == val4);
выводит это:
правда
ложьна 127L значение, так как обе ссылки (val1 и val2) указывают на один и тот же экземпляр объекта в памяти (кэшированный), он возвращает
true
.С другой стороны, для 128 значение, поскольку для него нет экземпляра, кэшированного в памяти, создается новый для любых новых назначений для коробочных значений, что приводит к двум различным экземплярам (указанным val3 и val4) и возвращению
false
о сравнении между ними.это происходит исключительно потому, что вы сравниваете два
Long
объект ссылки, а неlong
примитивные значения, с==
оператора. Если бы не этот механизм кэша, эти сравнения были бы всегда сбой, поэтому реальная проблема здесь заключается в сравнении коробочных значений с==
оператора.изменение этих переменных на примитивные
long
типы предотвратят это, но в случае, если вам нужно сохранить ваш код с помощьюLong
объекты, вы можете безопасно сделать эти сравнения со следующими подходами:System.out.println(val3.equals(val4)); // true System.out.println(val3.longValue() == val4.longValue()); // true System.out.println((long)val3 == (long)val4); // true
ИМО, это всегда хорошая идея, чтобы придерживаться с .равно () методы при работе с объектом сравнения.
отказ от ответственности: большинство сравнений потерпит неудачу, если любое из этих значений равно null (даже приведение к long вызовет исключение), поэтому для размещения этих сценариев необходимы дополнительные проверки.
ссылка ссылки:
num1
иnum2
длинные объекты. Вы должны использоватьequals()
сравнивать их.==
сравнение может иногда работать из-за того, как JVM помещает примитивы, но не зависит от него.if (num1.equals(num1)) { //code }
Java кэширует примитивные значения из -128 до 127. Когда мы сравниваем два долго объекты java внутренне введите приведите его к примитивному значению и сравните его. Но выше 127 длинный объект не получит тип каста. Java кэширует вывод с помощью .valueOf () метод.
это кэширование работает для байтов, коротких, длинных от -128 до 127. Для целочисленного кэширования работает от -128 до java.ленг.Целое число.IntegerCache.высокие или 127, в зависимости от того больше.(Мы можем установить значение верхнего уровня, до которого целочисленные значения должны кэшироваться с помощью java.ленг.Целое число.IntegerCache.высокий.)
For example: If we set java.lang.Integer.IntegerCache.high=500; then values from -128 to 500 will get cached and Integer a=498; Integer b=499; System.out.println(a==b) Output will be "true".
Float и двойные объекты никогда не кэшируются.
символ получит кэш от 0 до 127
вы сравниваете два объекта. так что == оператор проверяет равенство ссылок на объекты. Есть следующие способы сделать это.
1) тип приведения обоих объектов в примитивные значения и сравнить
(long)val3 == (long)val4
2) прочитайте значение объекта и сравните
val3.longValue() == val4.longValue()
3) Используйте метод equals () для сравнения объектов.
val3.equals(val4);
сравнение не примитивы (ака объекты) в Java с
==
сравнивает их ссылки вместо их значений.Long
- это класс, и таким образомLong
значения объектов.проблема в том, что разработчики Java хотели, чтобы люди использовали
Long
какlong
обеспечить совместимость, которая привела к концепции автобоксинга, которая по существу является функцией, котораяlong
- значения будут изменены наLong
-объекты и наоборот по мере необходимости. Поведение автобоксинг не совсем предсказуем все время, хотя, как это не совсем указано.поэтому, чтобы быть в безопасности и иметь предсказуемые результаты всегда используйте
.equals()
чтобы сравнить объекты и не полагаться на автобоксинг в этом случае:Long num1 = 127, num2 = 127; if(num1.equals(num2)) { iWillBeExecutedAlways(); }