Ganzzahl i = 3 gegen Ganzzahl i = neue Ganzzahl (3) [duplizieren]

7

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?

    
Shruti Rawat 05.07.2013, 17:32
quelle

9 Antworten

19

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%     
Jon Skeet 05.07.2013 17:35
quelle
5

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%     
zerocool 05.07.2013 17:34
quelle
2
%Vor%

Hier wird 3 automatisch eingereiht und daher zeigen i und j auf dieselbe Integer .

%Vor%

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.

    
Ravi Thapliyal 05.07.2013 17:40
quelle
2
  

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 .

    
Vishal K 05.07.2013 17:38
quelle
1

Nein, sollten sie nicht, denn Java kann vorgefertigte Integer-Objekte für kleine Zahlen beim Autoboxieren verwenden.

    
Ingo 05.07.2013 17:34
quelle
0

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.

    
William Morrison 05.07.2013 17:33
quelle
0

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.

    
quelle
0

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 .

    
Dancrumb 05.07.2013 17:37
quelle
0

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.

    
artapart 12.07.2013 10:15
quelle

Tags und Links