1. Einführung
In der Sprache Java gibt es zwei unterschiedliche Datenfamilien. Die erste – das sind primitive Typen: int, char, double, boolean und weitere. Sie sind einfach und schnell: Der Wert wird direkt in der Speicherzelle gespeichert. Die zweite Familie – das sind Referenztypen, also Objekte: Eine Variable speichert eine Referenz auf die Stelle im Speicher, an der sich das Objekt befindet.
Manchmal muss man einen Primitivwert als Objekt verwenden. Primitive sind jedoch von Haus aus keine Objekte. In solchen Fällen helfen spezielle Wrapper-Klassen.
Wrapper-Typen sind Klassen, die den Wert eines Primitivs kapseln und den Umgang damit wie mit einem Objekt ermöglichen. Zum Beispiel gilt: für int – die Klasse Integer, für double – Double, für char – Character, für boolean – Boolean. Solche Klassen stellen Methoden bereit: Integer.parseInt(), Double.isInfinite(), Character.isLetter(), Boolean.parseBoolean() u. a.
Beispiel, wie man aus einem Integer-Objekt aus einem int-Primitiv erhält:
// Primitiv
int a = 10;
// Wrapper-Objekt
Integer b = Integer.valueOf(10);
In der Variablen a steht die Zahl 10 selbst. Die Variable b hingegen enthält eine Referenz auf ein Objekt, das intern die 10 kapselt.
2. Wozu braucht man Wrapper
Ein Primitiv ist immer ein konkreter Wert; man kann ihn nicht auf null setzen. Ein Objekt kann hingegen nicht existieren und einen leeren Wert halten – das ist praktisch, wenn man „unbekannt“ oder „nicht vorhanden“ kennzeichnen möchte.
Ein Primitiv hat keine Methoden. Man kann bei einer Zahl nichts wie x.toString() aufrufen. Ein Wrapper bietet solche Möglichkeiten: Integer.parseInt("123") verwandelt eine Zeichenkette in eine Zahl, und eine Zahl kann man mit toString() in eine Zeichenkette umwandeln.
Fazit: Wrapper benötigt man überall dort, wo explizit ein Objekt verlangt wird – die Möglichkeit, null zu speichern, Methoden aufzurufen, Werte an ein API zu übergeben, das nur Objekte akzeptiert (z. B. Sammlungen wie List<Integer>).
Vollständige Liste der Wrapper-Typen
| Primitivtyp | Wrapper-Klasse |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3. Boxing und Unboxing
Wenn Sie manuell ein Wrapper-Objekt erstellen, nehmen Sie ein Primitiv und „verpacken“ es in ein Objekt:
int primitive = 42;
Integer wrapper = Integer.valueOf(primitive); // Boxing
Um den primitiven Wert wieder herauszuholen – zu „entpacken“ –, verwendet man z. B. intValue():
Integer wrapper = Integer.valueOf(42);
int primitive = wrapper.intValue(); // Unboxing
Autoboxing
Der Compiler fügt den Aufruf valueOf() automatisch hinzu, wenn Sie einem Wrapper eine Primitive zuweisen:
int a = 10;
Integer b = a; // Autoboxing (Integer.valueOf(a))
Unboxing
Der umgekehrte Fall – wenn ein Wrapper-Objekt dort verwendet wird, wo ein Primitiv benötigt wird:
Integer c = 20;
int d = c; // Unboxing (c.intValue())
int a = 10; // Primitiv
Integer b = a; // Autoboxing
Integer c = Integer.valueOf(20);
int d = c; // Unboxing
4. Fallstricke
Vergleich von Wrappern. Der Operator == vergleicht bei Objekten Referenzen, nicht Werte:
Integer m = 200;
Integer n = 200;
System.out.println(m == n); // false, weil es unterschiedliche Objekte sind
Java zwischenspeichert Wrapper für Zahlen im Bereich von -128 bis 127, daher liefert == manchmal true und manchmal false. Zum Vergleich der Werte verwenden Sie immer equals():
Integer x = 100;
Integer y = 100;
System.out.println(x == y); // true, im Cache-Bereich
System.out.println(x.equals(y)); // true, Vergleich nach Wert
NullPointerException beim Unboxing. Wenn der Wrapper null ist und Sie ihn unboxen – erhalten Sie eine Ausnahme:
Integer value = null;
int primitive = value; // Fehler! NullPointerException
Leistung und Speicher. Wrapper sind langsamer als Primitive und benötigen mehr Speicher. In Hotspots des Codes und bei großen Zahlenarrays sollten Sie Primitive bevorzugen.
5. Beispiele
Beispiele mit Integer und Double
Umwandlung einer Zeichenkette in eine Zahl:
String text = "123";
int number = Integer.parseInt(text);
System.out.println(number); // 123
Prüfen besonderer Gleitkommawerte:
double d = 1.0 / 0;
System.out.println(Double.isInfinite(d)); // true
double nan = 0.0 / 0.0;
System.out.println(Double.isNaN(nan)); // true
Beispiele mit Character
char speichert ein einzelnes Zeichen; der Wrapper Character bietet praktische Prüfungen:
char ch = 'A';
Character wrapper = ch; // Autoboxing
System.out.println(Character.isLetter(ch)); // true
System.out.println(Character.isDigit(ch)); // false
System.out.println(Character.toLowerCase(ch)); // 'a'
Beispiele mit Boolean
Der Primitive boolean kennt nur true/false. Der Wrapper Boolean erlaubt zusätzlich den Wert null:
Boolean flag = null; // zulässig
flag = Boolean.TRUE; // spezielle Konstante
System.out.println(flag); // true
Umwandlung von Zeichenketten in boolesche Werte:
String s1 = "true";
String s2 = "false";
boolean b1 = Boolean.parseBoolean(s1);
boolean b2 = Boolean.parseBoolean(s2);
System.out.println(b1); // true
System.out.println(b2); // false
GO TO FULL VERSION