EMZETT.
Login

Wrapper Classes

Kurz: Klassen, die einen primitiven Datentyp als Objekt “verpacken” — z. B. Integer für int, Double für double, Boolean für boolean.

Genauer: Collections wie List können nur Objekte speichern, keine primitiven Typen direkt — List<int> ist deshalb ungültig, List<Integer> dagegen funktioniert. Die automatische Umwandlung zwischen primitivem Typ und Wrapper (Autoboxing/Unboxing) übernimmt der Compiler meist unsichtbar, kann bei sehr vielen Umwandlungen aber Performance kosten.

Im Detail

int primitiv = 5;
Integer objekt = primitiv;      // Autoboxing: automatisch in Integer verpackt
int zurueck = objekt;           // Unboxing: automatisch wieder ausgepackt
 
List<Integer> zahlen = new ArrayList<>();
zahlen.add(10); // int wird automatisch zu Integer geboxt
 
Integer a = 100;
Integer b = 100;
System.out.println(a == b);     // true - kleine Werte (-128 bis 127) werden gecacht
 
Integer c = 200;
Integer d = 200;
System.out.println(c == d);     // false! - außerhalb des Caches, zwei echte Objekte
System.out.println(c.equals(d)); // true - Inhalt korrekt verglichen

Jeder primitive Typ hat genau eine passende Wrapper-Klasse: int → Integer, double → Double, boolean → Boolean, char → Character usw. Seit Java 5 übernimmt der Compiler die Umwandlung zwischen beiden Welten meist unsichtbar (Autoboxing beim Verpacken, Unboxing beim Auspacken) — praktisch, aber nicht kostenlos: jede Boxing-Operation kann ein neues Objekt auf dem Heap erzeugen, was in performancekritischen Schleifen mit sehr vielen Umwandlungen spürbar langsamer sein kann als reine primitive Arithmetik.

Eine bekannte Stolperfalle: Java cached kleine Integer-Werte zwischen -128 und 127 intern wieder, sodass == bei diesen Werten zufällig true liefert (wie beim a == b-Beispiel oben), außerhalb dieses Bereichs aber zwei separate Objekte entstehen und == false liefert. Genau wie bei String gilt deshalb: für einen zuverlässigen Wertvergleich von Wrapper-Objekten immer .equals() statt == verwenden. Ein zweites Risiko: Integer (Objekt) kann null sein, int (primitiv) niemals — ein automatisches Unboxing von null wirft eine NullPointerException.

Siehe auch: Non-primitive Types, Generics, Collections