EMZETT.
Login

Non-primitive Types

Kurz: Alle Datentypen, die keine der 8 primitiven Typen sind — also Objekte, z. B. String, Arrays, eigene Klassen und alle Wrapper Classes.

Genauer: Der zentrale Unterschied zu primitiven Typen: eine non-primitive-Variable speichert nicht den Wert selbst, sondern eine Referenz auf ein Objekt im Heap-Speicher — deshalb kann sie auch null sein (kein Objekt vorhanden), was bei primitiven Typen wie int nicht möglich ist.

Im Detail

String text = null; // gültig! null bedeutet "keine Referenz auf ein Objekt"
// int zahl = null;  // würde NICHT kompilieren - primitive Typen können nie null sein
 
String a = "Hallo";
String b = a;   // b zeigt auf DASSELBE Objekt wie a, keine Kopie!
a = "Neu";       // a zeigt jetzt auf ein anderes Objekt, b bleibt bei "Hallo"
 
int[] zahlen = {1, 2, 3};
int[] zweiteReferenz = zahlen;
zweiteReferenz[0] = 99; // ändert dasselbe Array-Objekt!
System.out.println(zahlen[0]); // 99 - auch "zahlen" sieht die Änderung

Der letzte Codeblock zeigt den wichtigsten praktischen Unterschied zu primitiven Typen: weil non-primitive Variablen nur eine REFERENZ auf ein Objekt speichern (nicht das Objekt selbst), teilen sich zwei Variablen mit derselben Referenz auch dasselbe zugrundeliegende Objekt — eine Änderung über die eine Variable ist auch über die andere sichtbar. Bei String fällt das in der Praxis selten auf, weil String-Objekte unveränderlich (immutable) sind: jede scheinbare “Änderung” (a = "Neu") erzeugt in Wahrheit ein komplett neues Objekt und lässt a nur darauf zeigen, statt das ursprüngliche "Hallo"-Objekt zu verändern. Bei veränderlichen Objekten wie Arrays oder eigenen Klassen ist dieses “geteilte Referenz”-Verhalten dagegen ein häufiger, überraschender Bug, wenn man versehentlich davon ausgeht, eine Kopie erhalten zu haben.

Vergleich mit == vs. .equals()

Weil non-primitive Variablen Referenzen speichern, vergleicht == bei ihnen standardmäßig, ob zwei Variablen auf dasselbe Objekt zeigen (Objektidentität), nicht ob der Inhalt gleich ist — ein häufiger Anfängerfehler ist if (a == b) bei zwei inhaltlich gleichen, aber separat erzeugten Objekten, was false liefert, obwohl die Werte identisch aussehen. Für inhaltlichen Vergleich braucht es .equals() (bei eigenen Klassen muss diese Methode selbst sinnvoll überschrieben werden, sonst verhält sie sich wie ==).

Garbage Collection und non-primitive Objekte

Da non-primitive Werte im Heap-Speicher leben, kümmert sich Java automatisch per Garbage Collector um deren Aufräumung, sobald kein Verweis mehr darauf existiert — anders als primitive Werte, die einfach mit dem Stack-Frame der Methode verschwinden, in der sie deklariert wurden. Ein Objekt, auf das keine Variable mehr zeigt, wird nicht sofort gelöscht, sondern irgendwann später vom Garbage Collector eingesammelt, sobald er läuft.

Siehe auch: Strings, Wrapper Classes, double, byte, Garbage Collector