class D {
public static void main(String args[]) {
Integer b2=128;
Integer b3=128;
System.out.println(b2==b3);
}
}
Wynik:
false
class D {
public static void main(String args[]) {
Integer b2=127;
Integer b3=127;
System.out.println(b2==b3);
}
}
Wynik:
true
Uwaga: liczby od -128 do 127 są prawdziwe.
Odpowiedzi:
Kiedy kompilujesz literał liczbowy w Javie i przypisujesz go do Integer (kapitału
I
), kompilator emituje:Ta linia kodu jest również generowana podczas korzystania z autoboxingu.
valueOf
jest zaimplementowany w taki sposób, że pewne liczby są „łączone” i zwraca to samo wystąpienie dla wartości mniejszych niż 128.Z kodu źródłowego Java 1.6, wiersz 621:
Wartość
high
można skonfigurować na inną wartość za pomocą właściwości systemowej.Jeśli uruchomisz program z tą właściwością systemową, wyjdzie prawda!
Oczywisty wniosek: nigdy nie polegaj na tym, że dwa odniesienia są identyczne, zawsze porównuj je z
.equals()
metodą.Więc
b2.equals(b3)
wypisze prawdę dla wszystkich logicznie równych wartości b2, b3.Zauważ, że
Integer
pamięć podręczna nie istnieje ze względu na wydajność, ale raczej w celu dostosowania się do JLS, sekcja 5.1.7 ; tożsamość obiektu należy podać dla wartości od -128 do 127 włącznie.Integer # valueOf (int) również dokumentuje to zachowanie:
źródło
false
. Właściwie może się to zdarzyć już dzisiaj, jako efekt uboczny zastosowania analizy ucieczki i zamiany skalarnej.Buforowanie autoboxu od -128 do 127. Jest to określone w JLS ( 5.1.7 ).
Prosta zasada do zapamiętania podczas pracy z obiektami to - użyj,
.equals
jeśli chcesz sprawdzić, czy dwa obiekty są „równe”, użyj,==
gdy chcesz sprawdzić, czy wskazują na tę samą instancję.źródło
Użycie pierwotnych typów danych, ints, dałoby w obu przypadkach wartość true, oczekiwany wynik.
Jednak ponieważ używasz obiektów typu Integer, operator == ma inne znaczenie.
W kontekście obiektów == sprawdza, czy zmienne odnoszą się do tego samego odniesienia do obiektu.
Aby porównać wartości obiektów należy użyć metody equals () np
który wskaże, czy b2 jest mniejsze niż b1, większe lub równe (szczegóły w API)
źródło
Jest to optymalizacja pamięci w języku Java.
źródło
Spójrz na Integer.java, jeśli wartość mieści się w zakresie od -128 do 127, użyje puli pamięci podręcznej, więc
(Integer) 1 == (Integer) 1
podczas(Integer) 222 != (Integer) 222
źródło
Inne odpowiedzi opisują, dlaczego można zaobserwować zaobserwowane efekty, ale to naprawdę nie ma znaczenia dla programistów (z pewnością interesujące, ale o czym należy zapomnieć podczas pisania właściwego kodu).
Aby porównać obiekty typu Integer pod kątem równości, użyj
equals
metody.Nie próbować porównać obiektów Integer równości za pomocą operatora tożsamości,
==
.Może się zdarzyć, że niektóre równe wartości są identycznymi obiektami, ale nie jest to coś, na czym należy polegać.
źródło
Napisałem co następuje, ponieważ ten problem nie dotyczy tylko liczby Integer. Mój wniosek jest taki, że częściej niż nie, jeśli używasz API nieprawidłowo, nadal widzisz nieprawidłowe zachowanie. Użyj go poprawnie i powinieneś zobaczyć poprawne zachowanie:
źródło