In Java arbeitest du nicht nur mit primitiven Datentypen wie int, double oder boolean, sondern auch mit den passenden Wrapper-Klassen wie Integer, Double und Boolean. Genau an dieser Stelle kommen Autoboxing und Unboxing ins Spiel. Die Begriffe klingen im ersten Moment technischer, als sie eigentlich sind. Am Ende geht es nur darum, dass Java in bestimmten Situationen automatisch zwischen einem primitiven Wert und dem passenden Objekt umwandelt.
Das ist praktisch, weil du dadurch oft weniger Code schreiben musst. Gleichzeitig ist es ein Thema, bei dem man schnell Fehler übersieht, wenn man noch nicht genau weiß, was im Hintergrund passiert. Vor allem dann, wenn null ins Spiel kommt oder du mit Collections wie List<Integer> arbeitest.
In diesem Artikel schauen wir uns das Thema mit einem einfachen, durchgängigen Beispiel an. So siehst du nicht nur, was Autoboxing und Unboxing bedeuten, sondern auch, wann Java das für dich übernimmt und wo du besser kurz innehalten solltest.
Was Autoboxing und Unboxing eigentlich sind
Autoboxing bedeutet, dass Java einen primitiven Wert automatisch in das passende Wrapper-Objekt umwandelt. Aus einem int wird also ein Integer. Unboxing ist genau das Gegenteil. Dabei wird aus einem Integer wieder ein int.
Schauen wir uns das direkt an:
int punkte = 10;
Integer verpacktePunkte = punkte; // Autoboxing
int neuePunkte = verpacktePunkte; // Unboxing
Früher musste man solche Umwandlungen deutlich sichtbarer schreiben. Heute erledigt Java das in vielen Fällen automatisch. Das macht den Code angenehmer lesbar, kann aber auch verschleiern, dass hier gerade tatsächlich eine Umwandlung passiert.
Wichtig ist dabei ein Unterschied, den du dir früh merken solltest: Ein int ist ein primitiver Datentyp. Ein Integer ist ein Objekt. Ein primitiver Wert kann nie null sein, ein Integer dagegen schon.
Genau deshalb behandelt Java diese beiden Typen nicht immer gleich, auch wenn sie auf den ersten Blick ähnlich wirken.
Wo dir das im Alltag begegnet
Autoboxing und Unboxing tauchen besonders oft bei Collections auf. Eine List kann nur Objekte speichern, keine primitiven Datentypen. Deshalb kannst du keine List<int> verwenden, sondern nur List<Integer>.
Nehmen wir ein kleines Beispiel mit Punkten aus mehreren Spielrunden:
import java.util.ArrayList;
import java.util.List;
public class PunkteDemo {
public static void main(String[] args) {
List<Integer> punkteListe = new ArrayList<>();
punkteListe.add(10);
punkteListe.add(20);
punkteListe.add(15);
int gesamt = 0;
for (Integer punkte : punkteListe) {
gesamt += punkte;
}
System.out.println("Gesamtpunkte: " + gesamt);
}
}
In punkteListe.add(10) passiert Autoboxing. Die 10 ist eigentlich ein int, wird aber automatisch zu einem Integer, damit sie in der Liste gespeichert werden kann.
In der Schleife passiert Unboxing. Die Variable punkte ist vom Typ Integer, aber bei gesamt += punkte; braucht Java einen primitiven Wert. Deshalb wird punkte automatisch in ein int umgewandelt.
Wenn du das verstanden hast, werden viele Stellen in Java-Code deutlich klarer. Du siehst dann schneller, warum ein Wert in einer Collection als Objekt auftaucht, im nächsten Ausdruck aber wie ein normaler int verwendet werden kann.
Der häufigste Stolperstein mit null
Richtig spannend wird es, wenn ein Integer den Wert null hat. Solange du ihn nur als Objekt behandelst, ist das erstmal kein Problem. Sobald Java aber unboxen soll, kracht es.
Hier ein einfaches Beispiel:
public class NullDemo {
public static void main(String[] args) {
Integer punkte = null;
int wert = punkte;
System.out.println(wert);
}
}
Dieser Code kompiliert, aber beim Ausführen bekommst du eine NullPointerException. Der Grund ist einfach: Java versucht aus null ein int zu machen. Das geht nicht, weil ein primitiver Datentyp keinen leeren Objektzustand kennt.
Genau deshalb solltest du bei Wrapper-Klassen immer kurz prüfen, ob null möglich ist. Das gilt besonders dann, wenn Werte aus einer Datenbank, aus einer API oder aus Benutzereingaben kommen.
So ist es sicherer:
public class NullDemoSicher {
public static void main(String[] args) {
Integer punkte = null;
int wert = punkte != null ? punkte : 0;
System.out.println(wert);
}
}
Hier legst du klar fest, was passieren soll, wenn kein Wert vorhanden ist. In diesem Beispiel wird dann einfach 0 verwendet.
Ein weiterer Punkt ist der Vergleich. Bei primitiven Datentypen vergleichst du Werte. Bei Objekten vergleichst du mit == erstmal Referenzen. Das kann zu Verwirrung führen:
Integer a = 100;
Integer b = 100;
System.out.println(a == b);
System.out.println(a.equals(b));
Wenn du Wrapper-Klassen vergleichst, ist equals() meistens die bessere Wahl, weil du damit den eigentlichen Inhalt vergleichst.
Fazit
Autoboxing und Unboxing nehmen dir in Java viel Schreibarbeit ab. Aus einem int wird automatisch ein Integer, und aus einem Integer wieder ein int, sobald der Kontext das verlangt. Das ist bequem und gehört im Alltag ganz normal dazu, vor allem bei Collections.
Trotzdem lohnt es sich, das Verhalten bewusst zu verstehen. Du solltest immer im Kopf behalten, dass Integer ein Objekt ist und deshalb null sein kann, während int das nicht kann. Genau an dieser Stelle entstehen viele der Fehler, die am Anfang unnötig Zeit kosten.
Wenn du dir nur eine Sache aus diesem Thema mitnimmst, dann diese: Die automatische Umwandlung ist hilfreich, aber sie passiert nicht magisch. Java macht hier klare Schritte im Hintergrund. Sobald du diese Schritte erkennst, liest du Code sicherer und findest Fehler schneller.
