Inkonsistentes Verhalten bei Java ==

8

Betrachten Sie diesen Code:

%Vor%

Es druckt:

%Vor%

Ich verstehe die erste false , der == Operator überprüft nur, ob zwei Referenzen am selben Objekt arbeiten, was in diesem Fall nicht der Fall ist.

Die folgenden true und false haben mich am Kopf kratzen. Warum würde Java i3 und i4 gleich betrachten, aber i1 und i2 anders? Beide wurden in Integer verpackt, sollte nicht beide als falsch bewertet werden? Gibt es einen praktischen Grund für diese Inkonsistenz?

    
andandandand 18.07.2009, 22:52
quelle

7 Antworten

15

Das Autoboxing von Primitiven in Objekten (wie es in Ihren Aufrufen von method verwendet wird, verwendet einen Cache mit kleinen Werten. Aus dem Java-Sprachspezifikation Abschnitt 5.1.7 :

  

Wenn der Wert p, der eingerahmt wird, wahr ist,   Falsch, ein Byte, ein Zeichen im Bereich   \ u0000 \ n007f, oder ein int oder kurz   Nummer zwischen -128 und 127, dann lassen   r1 und r2 sind die Ergebnisse von zweien   Boxenkonvertierungen von p. Es ist immer   der Fall, dass r1 == r2.

Der Diskussionsteil der darauf folgenden Spezifikation ist ebenfalls interessant. Bemerkenswerterweise kann eine JVM mehr -Werte zwischenspeichern, wenn sie das will - Sie können nicht sicher sein, was Sie tun können:

%Vor%     
Jon Skeet 18.07.2009, 22:58
quelle
7

Beim Autoboxing werden Ganzzahlen zwischen -128 und 127 zwischengespeichert, und das gleiche Wrapper-Objekt wird zurückgegeben. Das Gleiche gilt für boolesche Werte und Zeichenwerte zwischen \ u0000 und \ u007F

Das ist die meiste Zeit, aber es hängt von der JVM-Implementierung ab.

    
amorfis 18.07.2009 22:57
quelle
2

Das liegt daran, dass Boxing ganze Zahlen unter einem bestimmten Wert (128, denke ich) auf ein vorkonstruiertes Objekt und höhere Werte auf neue Objekte verweist.

    
Jorn 18.07.2009 22:55
quelle
1

Autoboxing verwendet Integer.valueOf (i) , nicht New Integer (i), um ein Objekt der Klasse Integer zu konstruieren.

Wie die anderen bereits gesagt haben, verwendet valueOf () einen Cache, hauptsächlich für die Speicherplatzeffizienz.

Verwenden Sie nicht == auf Referenztypen, es ist fast immer ein Fehler.

    
starblue 19.07.2009 06:55
quelle
0

Integer-Klasse enthält einen Cache einiger häufig verwendeter Instanzen. Der Bereich der Werte variiert im Allgemeinen von JVM zu JVM (manchmal ist auch konfigurierbar), aber im Allgemeinen ist der relevante Code etwas wie:

%Vor%

(Code von Sonne JDK 1.6)

Dies ist wie beim String-Interning, da es sowohl Speicher spart als auch die Testgleichheit mithilfe einer Referenz ermöglicht (z. B. == anstelle von gleich )

    
dfa 18.07.2009 23:00
quelle
0

Ich würde vermuten, dass das Wrapping versucht, die Anzahl der Integer-Objekte zu minimieren und nur ein Objekt zu erstellen, das 2 Speicher zu speichern darstellt.

Denken Sie daran, niemals == bei Objekten zu verwenden, von denen Sie nie wissen, was passiert.

    
Janusz 18.07.2009 22:57
quelle
0

Autoboxing verwendet einige Caching-Mechanismen. Normalerweise sollten Sie sich niemals auf == verlassen, verwenden Sie immer equals , um die Gleichheit zu prüfen.

    
fastcodejava 28.01.2010 11:23
quelle

Tags und Links