Frage

Betrachten Sie diesen Code:

class test {
   public static void main(String[] args) {
      test inst_test = new test();
      int i1 = 2000;
      int i2 = 2000;
      int i3 = 2;
      int i4 = 2;
      Integer Ithree = new Integer(2); // 1
      Integer Ifour = new Integer(2); // 2
      System.out.println( Ithree == Ifour );
      inst_test.method( i3 , i4 );
      inst_test.method( i1 , i2 );
   }
   public void method( Integer i , Integer eye ) {
      System.out.println(i == eye );
   }
}

Es druckt:

false
true
false

Ich verstehe den ersten false, Der == Operator prüft nur, ob zwei Referenzen an demselben Objekt funktionieren, was in diesem Fall nicht der Fall ist.

Folgende true und false Lass mich meinen Kopf kratzen. Warum sollte Java in Betracht ziehen? i3 und i4 gleich aber i1 und i2 anders? Beide wurden an Ganzzahl gewickelt, sollte nicht beide zu falsch bewerten? Gibt es einen praktischen Grund für diese Inkonsistenz?

War es hilfreich?

Lösung

Autoboxierung von Primitiven in Objekte (wie in Ihren Aufrufen an verwendet method Verwendet einen Cache mit kleinen Werten. Von dem Java -Sprachspezifikation Abschnitt 5.1.7:

Wenn der Wert P, der gepackt wird, ist wahr, falsch, ein Byte, ein Zeichen im Bereich u0000 bis u007f oder eine int oder eine Kurznummer zwischen -128 und 127, dann sei R1 und R2 die Ergebnisse von zwei Box -Konvertierungen, von p. Es ist immer der Fall, dass R1 == R2.

Der Diskussionsteil der Spezifikation unmittelbar auch ist interessant. Bemerkenswerterweise kann ein JVM -Cache Cache mehr Werte, wenn es will - Sie können sich nicht sicher sein, dass die Ergebnisse von Tun:

Integer i1 = 129;
Integer i2 = 129;
boolean b = (i1 == i2);

Andere Tipps

Beim Autoboxen 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

Dies ist das, was Sie die meiste Zeit erhalten, es hängt jedoch von der JVM -Implementierung ab.

Dies liegt daran, dass Boxen Ganzzahlen unter einem bestimmten Wert (128, glaube ich) auf ein vorkonstruiertes Objekt und höhere Werte auf neue Objekte beziehen.

Autoboxen verwendet Integer.Valueof (i), nicht neue Ganzzahl (i), um ein Objekt der Klassengülle zu konstruieren.

Wie die anderen gesagt haben, verwendet ValueOf () einen Cache, hauptsächlich für Platzeffizienz.

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

Die Ganzzahlklasse enthält einen Cache einiger häufig verwendeter Instanzen. Der Wertebereich variiert im Allgemeinen von JVM bis JVM (manchmal auch konfigurierbar), aber im Allgemeinen ist der entsprechende Code etwas wie:

public static Integer valueOf(int i) {
    if(i >= -128 && i <= IntegerCache.high)
        return IntegerCache.cache[i + 128];
    else
        return new Integer(i);
}

(Code von Sun Jdk 1.6)

Dies ist wie ein Schnitt für String, da beide Speicher Speicher speichern und die Gleichheit mit einer Referenz (z. == anstelle von gleich)

Ich würde vermuten, dass die Verpackung versucht, die Anzahl der Ganzzahlobjekte zu minimieren, und nur ein Objekt erstellt, das 2 darstellt, und den Speicher zu speichern.

Denken Sie nur daran, niemals == für Objekte zu verwenden, von denen Sie nie wissen, was passiert.

Autoboxing Verwenden Sie einen Caching -Mechanismus. Normalerweise solltest du dich niemals verlassen ==, Verwenden Sie immer equals Gleichheit überprüfen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top