TL; DR
Java buforuje wystąpienia w postaci liczb całkowitych od -128
do 127
. Ponieważ używasz ==
do porównywania odwołań do obiektów zamiast wartości , będą pasować tylko obiekty z pamięci podręcznej. Możesz albo pracować z long
rozpakowanymi wartościami pierwotnymi, albo używać ich .equals()
do porównywania Long
obiektów.
Wersja długa (gra słów)
Dlaczego jest problem z porównaniem zmiennej Long z wartością większą niż 127? Jeśli typ danych powyższej zmiennej jest pierwotny (długi), kod działa dla wszystkich wartości.
Java buforuje instancje obiektów typu Integer z zakresu od -128 do 127 . To mówi:
- Jeśli ustawisz na N Long zmienne wartość
127
( buforowana ), ta sama instancja obiektu będzie wskazywana przez wszystkie odwołania. (N zmiennych, 1 instancja)
- Jeśli ustawisz wartość N Long zmiennych
128
( nie buforowaną ), będziesz mieć instancję obiektu wskazywaną przez każde odwołanie. (N zmiennych, N wystąpień)
Dlatego to:
Long val1 = 127L;
Long val2 = 127L;
System.out.println(val1 == val2);
Long val3 = 128L;
Long val4 = 128L;
System.out.println(val3 == val4);
Wyprowadza to:
prawda
fałsz
W przypadku wartości 127L , ponieważ oba odwołania (wart1 i wart2) wskazują na tę samą instancję obiektu w pamięci (w pamięci podręcznej), zwraca true
.
Z drugiej strony, dla wartości 128 , ponieważ nie ma dla niej instancji w pamięci podręcznej, tworzony jest nowy dla każdego nowego przypisania dla wartości w pudełku, co powoduje dwie różne instancje (wskazywane przez val3 i val4) i powraca false
do porównanie między nimi.
Dzieje się tak wyłącznie dlatego, że z operatorem porównujesz dwa Long
odwołania do obiektów , a nie long
wartości pierwotne ==
. Gdyby nie ten mechanizm pamięci podręcznej, te porównania zawsze kończyłyby się niepowodzeniem, więc prawdziwym problemem jest tutaj porównanie wartości pudełkowych z ==
operatorem.
Zmiana tych zmiennych na long
typy prymitywne zapobiegnie temu, ale w przypadku, gdy musisz zachować swój kod przy użyciu Long
obiektów, możesz bezpiecznie dokonać tych porównań, stosując następujące podejścia:
System.out.println(val3.equals(val4)); // true
System.out.println(val3.longValue() == val4.longValue()); // true
System.out.println((long)val3 == (long)val4); // true
(Konieczne jest właściwe sprawdzenie zerowe, nawet w przypadku odlewów)
IMO , zawsze dobrze jest trzymać się metod .equals () podczas porównywania obiektów.
Linki referencyjne:
.longValue()
.