Nie mam pojęcia, dlaczego te wiersze kodu zwracają różne wartości:
System.out.println(Integer.valueOf("127")==Integer.valueOf("127"));
System.out.println(Integer.valueOf("128")==Integer.valueOf("128"));
System.out.println(Integer.parseInt("128")==Integer.valueOf("128"));
Dane wyjściowe to:
true
false
true
Dlaczego pierwszy powraca, true
a drugi powraca false
? Czy jest coś innego, że nie wiem, od 127
a 128
? (Oczywiście, że wiem, że 127
< 128
.)
Ponadto, dlaczego trzeci powraca true
?
Przeczytałem odpowiedź na to pytanie , ale wciąż nie wiedziałem, jak można ją zwrócić true
i dlaczego zwraca kod w drugiej linii false
.
java
integer
comparison
DnR
źródło
źródło
.equals()
, w przeciwnym razie wszystkie zakłady są wyłączone.Odpowiedzi:
Jest tutaj uderzająca różnica.
valueOf
zwracaInteger
obiekt, którego wartości mogą być buforowane między -128 a 127. Dlatego pierwsza wartość zwracatrue
- jest buforowana - a druga wartośćfalse
- 128 nie jest wartością buforowaną, więc otrzymujesz dwa osobneInteger
wystąpienia .Ważne jest, aby pamiętać , że porównujesz odniesienia
Integer#valueOf
, a jeśli porównujesz wartość, która jest większa niż obsługiwana przez pamięć podręczną, nie oceni tegotrue
, nawet jeśli przeanalizowane wartości są równoważne (przypadek:)Integer.valueOf(128) == Integer.valueOf(128)
. Państwo musi użyćequals()
zamiast.parseInt
zwraca prymitywint
. To dlatego zwraca wartość trzecietrue
-128 == 128
jest oceniany, a to oczywiścietrue
.Teraz zdarza się sporo, aby uzyskać ten trzeci wynik
true
:Konwersja rozpakowywania występuje w odniesieniu do operatora równoważności, którego używasz, oraz typów danych, które masz - a mianowicie
int
iInteger
. Oczywiście dostajeszInteger
zvalueOf
prawej strony.Po konwersji porównujesz dwie prymitywne
int
wartości. Porównanie odbywa się tak, jak można by się tego spodziewać w odniesieniu do prymitywów, więc kończy się porównywanie128
i128
.źródło
List
. Drugi to prymitywny, który jest tylko surową wartością.==
. zresztą teraz jest jasne.Integer
Klasa ma statyczną pamięć, która przechowuje 256 specjalneInteger
obiekty - jeden dla każdej wartości pomiędzy -128 i 127. Mając to na uwadze, należy rozważyć różnicę pomiędzy tymi trzema.To (oczywiście) tworzy zupełnie nowy
Integer
przedmiot.Zwraca to
int
pierwotną wartość po parsowaniuString
.Jest to bardziej złożone niż inne. Zaczyna się od analizy
String
. Następnie, jeśli wartość wynosi od -128 do 127, zwraca odpowiedni obiekt ze statycznej pamięci podręcznej. Jeśli wartość znajduje się poza tym zakresem, wówczas wywołujenew Integer()
i przekazuje wartość, aby uzyskać nowy obiekt.Teraz rozważ trzy wyrażenia w pytaniu.
Zwraca wartość true, ponieważ
Integer
wartość tego parametru wynosi 127, która jest dwukrotnie pobierana ze statycznej pamięci podręcznej i porównywana z samym sobą. W grę wchodzi tylko jedenInteger
obiekt, więc to się zwracatrue
.Zwraca
false
, ponieważ 128 nie znajduje się w statycznej pamięci podręcznej. Tak więc powstaje nowyInteger
dla każdej strony równości. Ponieważ istnieją dwa różneInteger
obiekty, a==
dla obiektów zwraca się tylkotrue
wtedy, gdy obie strony są dokładnie tym samym obiektem, tak właśnie będziefalse
.Porównuje to pierwotną
int
wartość 128 po lewej stronie, z nowo utworzonymInteger
obiektem po prawej stronie. Ponieważ jednak nie ma sensu porównywaćint
anInteger
, Java automatycznie rozpakuje plikInteger
przed wykonaniem porównania; więc kończysz na porównaniuint
doint
. Ponieważ prymityw 128 jest równy sobie, zwraca totrue
.źródło
Zadbaj o zwrot wartości z tych metod. Metoda valueOf zwraca instancję liczby całkowitej:
Metoda parseInt zwraca wartość całkowitą (typ pierwotny):
Objaśnienie do porównania:
W twojej sytuacji (zgodnie z powyższymi zasadami):
To wyrażenie porównuje odwołania do tego samego obiektu, ponieważ zawiera wartość całkowitą z przedziału od -128 do 127, więc zwraca
true
.Wyrażenie to porównuje odniesienia do różnych obiektów, ponieważ zawierają wartości całkowite spoza <-128, 127>, więc zwraca
false
.To wyrażenie porównuje pierwotną wartość (lewa strona) i odniesienie do obiektu (prawa strona), więc prawa strona zostanie rozpakowana, a jego prymitywny typ zostanie porównany z lewą, więc zwróci
true
.źródło
==
, ponieważ są to różne obiekty.Obiekty całkowite buforują od -128 do 127 z 256 liczb całkowitych
Nie należy porównywać referencji do obiektów z == lub ! = . Powinieneś użyć . równa się (..) zamiast, lub lepiej - użyj pierwotnej int zamiast Integer.
parseInt : Analizuje argument ciągu jako liczbę całkowitą ze znakiem dziesiętnym. Wszystkie znaki w ciągu muszą być cyframi dziesiętnymi, z tym wyjątkiem, że pierwszy znak może być znakiem minus ASCII „-” („\ u002D”), aby wskazać wartość ujemną. Wynikowa wartość całkowita jest zwracana, dokładnie tak, jakby argument i podstawa 10 zostały podane jako argumenty do metody parseInt (java.lang.String, int).
valueOf Zwraca obiekt typu Integer zawierający wartość wyodrębnioną z określonego ciągu po przeanalizowaniu z podstawką podaną przez drugi argument. Pierwszy argument jest interpretowany jako reprezentujący liczbę całkowitą ze znakiem w podstawce podanej przez drugi argument, dokładnie tak, jakby argumenty zostały przekazane metodzie parseInt (java.lang.String, int). Wynikiem jest obiekt typu Integer, który reprezentuje wartość całkowitą określoną przez ciąg.
równoważny
radix - podstawa używana przy interpretacji s
więc jeśli jesteś równy
Integer.valueOf()
liczbie całkowitej między nimi-128 do 127 zwraca true w twoim stanie
dla
lesser than
-128 igreater than
127 dajefalse
źródło
Aby uzupełnić podane odpowiedzi, zwróć również uwagę na następujące kwestie:
Ten kod wydrukuje również:
false
Jak twierdził użytkownik Jay w komentarzu do zaakceptowanej odpowiedzi, należy zachować ostrożność podczas używania operatora
==
na obiektach, tutaj sprawdza się, czy oba odniesienia są takie same, co nie jest, ponieważ są one różnymi celami, chociaż reprezentują one bardzo ta sama wartość. Aby porównać obiekty, należyequals
zamiast tego użyć metody:Spowoduje to wydrukowanie:
true
Możesz zapytać: Ale dlaczego wydrukowano pierwszą linię
true
? . Sprawdzając kod źródłowyInteger.valueOf
metody, możesz zobaczyć:Jeśli parametr jest liczbą całkowitą między
IntegerCache.low
(domyślnie -128) aIntegerCache.high
(obliczona w czasie wykonywania przy minimalnej wartości 127), zwracany jest wstępnie przydzielony (buforowany) obiekt. Tak więc, gdy użyjesz 127 jako parametru, otrzymasz dwa odwołania do tego samego buforowanego obiektu i uzyskasztrue
porównanie odniesień.źródło