TL; DR
Java кешує в коробках цілі екземпляри від -128до 127. Оскільки ви використовуєте ==для порівняння посилань на об'єкти замість значень , відповідають лише кешовані об'єкти. Або працюйте з longнепоміченими примітивними значеннями або використовуйте .equals()для порівняння Longоб'єктів.
Довга (призначена для каламбуру) версія
Чому існує проблема порівняння змінної Long зі значенням, що перевищує 127? Якщо тип даних вищевказаної змінної є примітивним (довгим), то код працює для всіх значень.
Java кешує об'єкти об'єктів Integer з діапазону від -128 до 127 . Це сказав:
- Якщо встановити значення N Long змінних
127( кешоване ), один і той же екземпляр об'єкта буде вказуватися всіма посиланнями. (N змінних, 1 примірник)
- Якщо ви встановите на N Long змінних значення
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
(Правильна нульова перевірка необхідна навіть для кастингів)
IMO , завжди корисно дотримуватися методів .equals () при роботі з об'єктами порівнянь.
Довідкові посилання:
.longValue().