Сравнение упакованных длинных значений 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 86

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(); }