41 Stimmen

Integer-Wrapper-Objekte teilen sich die gleichen Instanzen nur innerhalb des Wertes 127?

Hier sind sie die gleiche Instanz:

Integer integer1 = 127;
Integer integer2 = 127;
System.out.println(integer1 == integer2);  // outputs "true"

Aber hier handelt es sich um unterschiedliche Fälle:

Integer integer1 = 128;
Integer integer2 = 128;
System.out.println(integer1 == integer2);  // outputs "false"

Warum teilen sich die Wrapper-Objekte dieselbe Instanz nur innerhalb des Wertes 127?

38voto

axtavt Punkte 233070

Weil es in der Java-Sprachenspezifikation festgelegt ist.

JLS 5.1.7 Umwandlung von Boxen :

Wenn der Wert p verpackt zu sein, ist true , false , a byte oder eine char im Bereich \u0000 à \u007f oder ein int o short Zahl zwischen -128 und 127 (einschließlich), dann lassen Sie r1 y r2 sind die Ergebnisse zweier beliebiger Boxumwandlungen von p . Es ist immer der Fall, dass r1 == r2 .

Im Idealfall wird ein bestimmter primitiver Wert geboxt p würde immer eine identische Referenz ergeben. In der Praxis ist dies mit den vorhandenen Implementierungstechniken möglicherweise nicht machbar. Die obigen Regeln sind ein pragmatischer Kompromiss. Die obige letzte Klausel verlangt, dass bestimmte gemeinsame Werte immer in ununterscheidbare Objekte gepackt werden. Die Implementierung kann diese Werte im Cache speichern, sei es träge oder eifrig. Für andere Werte verbietet diese Formulierung jegliche Annahmen über die Identität der gepackten Werte von Seiten des Programmierers. Dies würde die gemeinsame Nutzung einiger oder aller dieser Referenzen ermöglichen (aber nicht erfordern).

Dadurch wird sichergestellt, dass in den meisten Fällen das gewünschte Verhalten erreicht wird, ohne dass es zu unangemessenen Leistungseinbußen kommt, insbesondere bei kleinen Geräten. Weniger speicherbegrenzte Implementierungen könnten zum Beispiel alle char y short Werte, als auch int y long Werte im Bereich von -32K bis +32K.

12voto

Lachezar Balev Punkte 10847

Die Quelle von java.lang.Integer:

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);
    }

Zum Wohl!

8voto

Peter Lawrey Punkte 511323

Übrigens können Sie Ihren Code verkürzen auf

System.out.println("Integer 127 == " + ((Integer) 127 == (Integer) 127));
System.out.println("Integer 128 == " + ((Integer) 128 == (Integer) 128));

for(int i=0;i<5;i++) {
    System.out.println(
     "Integer 127 system hash code " + System.identityHashCode((Integer) 127)
     + ", Integer 128 system hash code "+System.identityHashCode((Integer) 128));
}

druckt

Integer 127 == true
Integer 128 == false
Integer 127 system hash code 1787303145, Integer 128 system hash code 202703779
Integer 127 system hash code 1787303145, Integer 128 system hash code 1584673689
Integer 127 system hash code 1787303145, Integer 128 system hash code 518500929
Integer 127 system hash code 1787303145, Integer 128 system hash code 753416466
Integer 127 system hash code 1787303145, Integer 128 system hash code 1106961350

Sie können sehen, dass 127 jedes Mal dasselbe Objekt ist, während das Objekt für 128 unterschiedlich ist.

1voto

Kru Punkte 4119

Denn kleine Werte im Bereich [-128, 127] werden zwischengespeichert, größere Werte nicht.

Um ganze Zahlen zu verpacken, verwendet Java http://download.oracle.com/javase/6/docs/api/java/lang/Integer.html#valueOf%28int%29

1voto

Daniel Kutik Punkte 6937

Zusätzlich zu den anderen Antworten möchte ich hinzufügen, dass == vergleicht nur die Objektreferenzen. Verwenden Sie .equals() stattdessen:

Integer integer1=128;
Integer integer2=128;
if(integer1.equals(integer2))
  System.out.println(true);
else
  System.out.println(false);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X