Ich vergleiche 2 Stück Code. Zuerst
%Vor%Zweitens,
%Vor% Ich habe Zweifel, dass im ersten Ausschnitt, warum i==j
gedruckt wird? Sollten die Referenzen nicht anders sein?
Es geht darum, wie Boxen funktioniert. Aus dem JLS Abschnitt 5.1.7 :
Wenn der Wert p, der eingerahmt wird, wahr, falsch, ein Byte oder ein Zeichen im Bereich \ u0000 bis \ u007f oder eine int oder kurze Zahl zwischen -128 und 127 (einschließlich) ist, dann seien r1 und r2 die Ergebnisse von zwei Boxen Umbauten von p. Es ist immer der Fall, dass r1 == r2.
Grundsätzlich muss eine Java-Implementierung die eingerahmten Repräsentationen für entsprechend kleine Werte zwischenspeichern und darf mehr zwischenspeichern. Der ==
-Operator vergleicht nur Referenzen, so dass er spezifisch erkennt, ob sich die beiden Variablen auf dasselbe Objekt beziehen. Im zweiten Code-Snippet werden sie definitiv nicht, da new Integer(3)
definitiv nicht die gleiche Referenz wie irgendeine zuvor erstellte ist ... es erzeugt immer ein neues Objekt.
Aufgrund der obigen Regeln muss dieser Code immer das gleiche Ergebnis liefern:
%Vor%Das könnte in beide Richtungen gehen:
%Vor%Java pools Integer zwischen -128 und 127 und daher sind beide Referenzen gleich.
%Vor%Dies führt zu Autoboxing und 3 wird in Integer 3 konvertiert. Also, weil ich mich auf ein Integer-Objekt im konstanten Pool beziehe, wird jetzt, wenn du j = 3 machst, dieselbe Referenz wie die von j j zugewiesen.
Während unterhalb des Codes:
%Vor%führt immer zu einer neuen Integer-Erstellung in Heap. Dies ist nicht gepoolt. Und deshalb sehen Sie, dass beide Referenzen sich auf verschiedene Objekte beziehen. Was ergibt
%Vor% Hier wird 3
automatisch eingereiht und daher zeigen i
und j
auf dieselbe Integer
.
Hier zeigt i
auf die automatisch eingereihte Integer
, während j
auf eine neue Integer
zeigt und daher die Referenzen den Operatorgleichheit ==
nicht bestehen.
Aber hier ist noch etwas zum Nachdenken.
%Vor% Warum? Denn das automatische Boxing teilt Integer
-Instanzen nur zwischen -128 und 127. Dieses Verhalten kann jedoch bei verschiedenen Java-Implementierungen unterschiedlich sein.
Ich habe Zweifel, dass im ersten Ausschnitt, warum ich == j gedruckt wird? Sollten die Referenzen nicht anders sein?
Weil,
%Vor% verwenden intern Integer # valueOf () um autoBoxing
auszuführen. Und Orakel doc sagt über valueOf()
Methode, die:
Gibt eine Integer-Instanz zurück, die den angegebenen int-Wert darstellt. Wenn ein new Integer-Instanz ist nicht erforderlich, diese Methode sollte generell sein wird vor dem Konstruktor Integer (int) verwendet, wie diese Methode ist wahrscheinlich deutlich bessere Raum - und Zeitleistung durch häufig angeforderte Werte zwischenspeichern. Diese Methode wird immer zwischengespeichert Werte im Bereich von -128 bis einschließlich 127 und können andere Werte zwischenspeichern außerhalb dieses Bereichs.
Da der Wert 3
daher zwischengespeichert wird, verweisen beide Variablen i
und j
auf dasselbe Objekt. Also, i==j
gibt true
zurück. Integer#valueOf()
verwendet Fliegengewichtsmuster .
Weil im zweiten Teil des Codes Ihre erste Ganzzahl automatisch eingereiht wird, während die zweite nicht.
Dies bedeutet, dass eine neue Integer-Instanz im laufenden Betrieb erstellt wird. Diese 2 Objektinstanzen sind unterschiedlich. Die Gleichheitsprüfung gibt dort false zurück, da die beiden Instanzen tatsächlich unterschiedliche Speicherbausteine sind.
Interpreter / JIT-Optimierer kann alle 3's in derselben Box ablegen. Aber wenn Sie ein "neues" erzwingen, erhalten Sie eine andere Adresse.
Versuchen Sie
%Vor%dann sehen Sie, dass die Adresse des J für die erste Version geändert wurde.
In ähnlicher Weise wie bei Strings, wenn Autoboxing verwendet wird, z. B. in
%Vor% Java kann aus einem Pool vorgefertigter Objekte zeichnen. Im Fall von j
gibt es bereits eine Integer
-Instanz, die den Wert von 3
im Pool darstellt, also wird davon ausgegangen. Daher zeigen i
und j
auf dasselbe, also i == j
.
In Ihrem zweiten Beispiel instanziieren Sie explizit ein neues Integer
-Objekt für j
, also zeigen i
und j
auf verschiedene Objekte, also i != j
.
Im folgenden Codeabschnitt:
%Vor%Hier vergleicht "==" die Referenz miteinander und nicht den Wert. Also, Integer i und j beziehen sich beide auf die gleiche Referenz im Speicher.
während im folgenden Codeabschnitt:
%Vor%Der Verweis auf beide Werte wird geändert, weil 'j' ein neu erstelltes Objekt / eine Referenz von Integer im Speicher ist, während 'i' sich nur auf einen Wert bezieht.
Daher ist der Ausgang des ersten Codes "i == j" und der zweite Code hat keinen Ausgang.
Hoffe, das hilft.
Tags und Links java