TL; DR
Java buforuje wystąpienia w postaci liczb całkowitych od -128do 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 longrozpakowanymi wartościami pierwotnymi, albo używać ich .equals()do porównywania Longobiektó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 falsedo 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 longwartoś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 longtypy prymitywne zapobiegnie temu, ale w przypadku, gdy musisz zachować swój kod przy użyciu Longobiektó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().