Appearance
Autoboxing / Unboxing β
Notizen β
Autoboxing ist die automatische Konvertierung eines primitiven Typs in sein Wrapper-Objekt. Unboxing ist das Gegenteil: ein Wrapper-Objekt wird automatisch in den primitiven Typ zurΓΌckgewandelt.
In Java gibt es 8 primitive Datentypen und jeder dieser Typen hat eine zugehΓΆrige Wrapper-Klasse:
| Primitiv | Wrapper |
|---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
boolean | Boolean |
char | Character |
Wrapper werden gebraucht, weil Collections wie List<Integer> keine primitiven Typen akzeptieren (Generics funktionieren nur mit Objekten).
Autoboxing: primitiv β Objekt β
java
int zahl = 42;
Integer boxed = zahl; // Autoboxing: int β Integer
List<Integer> liste = new ArrayList<>();
liste.add(5); // Autoboxing: int 5 β Integer.valueOf(5)Der Compiler wandelt das intern zu Integer.valueOf(42) um.
Unboxing: Objekt β primitiv β
java
Integer boxed = Integer.valueOf(100);
int unboxed = boxed; // Unboxing: Integer β int
Integer a = 10;
int summe = a + 5; // Unboxing: a wird zu int fΓΌr die AdditionDer Compiler wandelt das intern zu boxed.intValue() um.
Wichtige Fallstricke β
NullPointerException beim Unboxing β
java
Integer x = null;
int y = x; // NullPointerException! null.intValue() schlΓ€gt fehlWrapper-Klassen kΓΆnnen null enthalten, primitive Typen jedoch nicht. Deshalb immer auf null prΓΌfen, bevor ein Wrapper-Objekt in einen primitiven Typ umgewandelt wird.
== vs equals() bei Wrapper-Objekten β
java
Integer a = 200;
Integer b = 200;
System.out.println(a == b); // false! (verschiedene Objekte)
System.out.println(a.equals(b)); // true (gleicher Wert)== vergleicht bei Objekten die Referenz (Speicheradresse), nicht den Wert. Deshalb immer equals() verwenden, wenn Wrapper-Werte verglichen werden sollen.
Achtung β Integer Cache:
Integer.valueOf()cached Werte von -128 bis 127. In diesem Bereich liefert==zufΓ€lligtrue, weil beide Variablen auf dasselbe gecachte Objekt zeigen β auΓerhalb davon nicht mehr.
java
Integer a = 127;
Integer b = 127;
System.out.println(a == b); // true (Cache!)
Integer c = 128;
Integer d = 128;
System.out.println(c == d); // false (verschiedene Objekte)Performance β
java
Long summe = 0L;
for (int i = 0; i < 1_000_000; i++) {
summe += i; // StΓ€ndiges Boxing/Unboxing β langsam!
}In performance-kritischen Loops lieber long statt Long verwenden. Jedes Boxing erzeugt ein neues Objekt auf dem Heap β bei Millionen von Iterationen ist das spΓΌrbar.
Interview-Fragen β
Was ist Autoboxing und Unboxing? β
Antwort: Autoboxing ist die automatische Umwandlung eines primitiven Typs in die entsprechende Wrapper-Klasse (int β Integer). Unboxing ist das Gegenteil: die Wrapper-Klasse wird automatisch in den primitiven Typ zurΓΌckgewandelt (Integer β int). Beides erledigt der Compiler im Hintergrund β aus Integer i = 42 wird intern Integer.valueOf(42), aus int x = i wird i.intValue().
Warum existieren Wrapper-Klassen ΓΌberhaupt? β
Antwort: Generics in Java funktionieren nur mit Objekten, nicht mit primitiven Typen. Deshalb braucht man z. B. List<Integer> statt List<int>. AuΓerdem bieten Wrapper-Klassen nΓΌtzliche Hilfsmethoden wie Integer.parseInt(), Integer.MAX_VALUE oder Integer.toBinaryString(), die bei primitiven Typen nicht verfΓΌgbar sind.
Was passiert, wenn ein null-Wrapper ungeboxed wird? β
Antwort: Es wird eine NullPointerException geworfen. Der Compiler wandelt z. B. int y = x intern in x.intValue() um β wenn x null ist, schlΓ€gt das fehl. Deshalb immer auf null prΓΌfen, wenn Wrapper-Objekte aus Collections oder Methoden-RΓΌckgaben kommen.
Was ist der Integer Cache und welche Werte sind betroffen? β
Antwort: Integer.valueOf() cached Objekte im Bereich -128 bis 127. In diesem Bereich zeigen zwei Integer-Variablen mit demselben Wert auf dasselbe Objekt im Speicher, weshalb == dort true liefert. AuΓerhalb dieses Bereichs werden neue Objekte erstellt, und == liefert false β auch wenn der Wert gleich ist. Das ist ein klassischer Interview-Stolperstein.
Warum sollte man bei Wrapper-Objekten equals() statt == verwenden? β
Antwort: == vergleicht Referenzen (Speicheradressen), nicht Werte. Zwei Integer-Objekte mit demselben Wert kΓΆnnen unterschiedliche Objekte im Heap sein, weshalb == dann false liefert. equals() vergleicht den tatsΓ€chlichen Wert und ist daher die sichere Wahl. Im Cache-Bereich (-128 bis 127) wΓ€re == zufΓ€llig korrekt β aber darauf sollte man sich nie verlassen.
Welche Performance-Probleme kann Autoboxing verursachen? β
Antwort: Jedes Boxing erzeugt ein neues Objekt auf dem Heap, was Garbage-Collection-Druck erzeugt. In Loops mit vielen Iterationen kann das erheblich langsamer sein als die Verwendung primitiver Typen. Faustregel: In performance-kritischem Code int, long, double bevorzugen und Wrapper nur dort einsetzen, wo sie wirklich nΓΆtig sind (Collections, Generics).
Wo genau passiert Autoboxing β im Compiler oder zur Laufzeit? β
Antwort: Der Compiler fΓΌgt die Boxing- und Unboxing-Aufrufe bereits beim Kompilieren ein (Integer.valueOf() bzw. .intValue()). Zur Laufzeit gibt es kein "Autoboxing" mehr β im Bytecode sind es ganz normale Methodenaufrufe. Man kann das mit javap -c im dekompilierten Bytecode sehen.