2010-07-28 3 views
16
public class Main { 
    /** 
     * @param args the command line arguments */ 
    public static void main(String[] args) { 
     // TODO code application logic here 
     int a1 = 1000, a2 = 1000; 
     System.out.println(a1==a2);//=>true 
     Integer b1 = 1000, b2 = 1000; 
     System.out.println(b1 == b2);//=>false 
     Integer c1 = 100, c2 = 100; 
     System.out.println(c1 == c2);//=>true 
    } 

} 

Warum ist b1 == b2 falsch und c1 == c2 wahr?Java Frage zu Autoboxing und Objekt Gleichheit/Identität

Antwort

0

Die Antwort, die Sie wollen, ist here

2

Sie die Antwort finden Sie hier:

Strangest language feature in der 6. Antwort.

Edit: Entschuldigung nicht sehr die Antwort. Der Punkt ist, dass == Referenzen vergleicht, keine Werte, wenn Sie es mit Ganzzahl verwenden. Aber mit int "==" bedeutet gleich.

36

Gelesen this.

Java verwendet einen Pool für Integer s im Bereich von -128 bis 127

Das heißt, wenn Sie ein Integer mit Integer i = 42; und seinem Wert zwischen -128 und 128, kein neues Objekt erstellen wird erstellt, aber die entsprechende aus dem Pool wird zurückgegeben. Deshalb ist c1 tatsächlich identisch zu c2.

(Ich nehme an, Sie wissen, dass == Referenzen vergleicht, keine Werte, wenn auf Objekte angewendet).

+0

danke Felix Kling sehr. Ich habe diesen Code verstanden – OOP

+0

Das erklärt nicht, warum a1 == a2. – simon

+1

Die Frage war über 'b1 == b2' und' c1 == c2', wenn ich mich nicht irre. –

2

Da Integer für einige wenige Zahlen wie Enumeration ist, gibt es immer dieselbe Instanz. Aber höhere Zahlen erzeugen neue Instanzen von Ganzzahl und Operator == vergleicht ihre Referenzen

11

Die richtigen Antworten wurden bereits gegeben. Aber nur um meine zwei Cent hinzuzufügen:

Integer b1 = 1000, b2 = 1000; 

Das ist schrecklich Code. Objekte sollten als Objekte über Konstruktoren oder Factory-Methoden initialisiert werden. Z.B.

// let java decide if a new object must be created or one is taken from the pool 
Integer b1 = Integer.valueOf(1000); 

oder

// always use a new object 
Integer b2 = new Integer(1000); 

Dieser Code

Integer b1 = 1000, b2 = 1000; 

auf der anderen Seite bedeutet, dass Integer ein primitives war, was es nicht ist. Eigentlich, was Sie sehen, ist eine Abkürzung für

Integer b1 = Integer.valueOf(1000), b2 = Integer.valueOf(1000); 

und Integer nur Pools Objekte von -127 bis 127, so wird es zwei neue Objekte in diesem Fall erstellen. Also obwohl 1000 = 1000, b1! = B2. Dies ist der Hauptgrund, warum ich Auto-Boxen hasse.

+0

Vielen Dank Seanizer! – OOP

+0

Warum der Downvote? –

2
public static Integer valueOf(int i) { 
     final int offset = 128; 
     if (i >= -128 && i <= 127) { // must cache 
      return IntegerCache.cache[i + offset]; 
     } 
     return new Integer(i); 
    } 

Aus diesem Grund sind Sie in einem Fall wahr, und in anderen falsch!

+0

+1 für dieses Zitat aus Quellen. Auch die erste Antwort mit korrekter Reichweite! –

0

Wenn autounboxing auch gearbeitet hatte, als Gleichheit mit dem ‚==‘ Operator Überprüfung tun könnten Sie schreiben:

Long notNullSafeLong1 = new Long(11L) 
    Long notNullSafeLong2 = new Long(22L) 
    if (notNullSafeLong1 == notNullSafeLong2) { 
     do suff 

Dies würde eine Überschreibung für == Implementierung, so dass null == someLong falsch ist und die Sonderfall Null == Null ist wahr. Stattdessen müssen wir

Long notNullSafeLong1 = new Long(11L) 
    Long notNullSafeLong2 = new Long(22L) 
    if ((notNullSafeLong1 == null && notNullSafeLong2 == null) || 
     (notNullSafeLong1 != null && notNullSafeLong2 != null & 
     notNullSafeLong1.equals(notNullSafeLong2)) { 
     do suff  

Dies ist alittle ausführlicher als das erste Beispiel gleich() und Test für

null verwenden - wenn autounboxing für den ‚==‘ Operator gearbeitet hatte.