Non-primitive Types (Referenztypen)
Kurz: Datentypen, die keinen Wert direkt speichern, sondern eine Referenz (Verweis) auf ein Objekt im Speicher — im Gegensatz zu primitiven Typen wie byte oder double, die ihren Wert direkt enthalten.
Genauer: Weil eine Variable eines Referenztyps nur einen Verweis speichert, können mehrere Variablen auf dasselbe zugrunde liegende Objekt zeigen — eine Änderung über die eine Variable wirkt sich dann auch auf die andere aus, was bei primitiven Typen (jede Variable hat ihre eigene, unabhängige Kopie) nicht passiert. Klassische Beispiele für Referenztypen sind Objekte, Arrays und Strings.
Im Detail
Der Unterschied zwischen primitiven und Referenztypen zeigt sich am deutlichsten im Speicherverhalten:
int a = 5;
int b = a; // b bekommt eine UNABHÄNGIGE Kopie von 5
b = 10;
System.out.println(a); // immer noch 5
int[] arr1 = {1, 2, 3};
int[] arr2 = arr1; // arr2 zeigt auf DASSELBE Array wie arr1
arr2[0] = 99;
System.out.println(arr1[0]); // gibt 99 aus - dasselbe Array!Diese Unterscheidung wirkt sich auch darauf aus, wie Werte an Funktionen übergeben werden (siehe Parameter): Ein primitiver Wert wird beim Übergeben kopiert, ein Referenztyp übergibt nur den Verweis — Änderungen daran innerhalb der Funktion sind auch nach ihrem Ende beim Aufrufer sichtbar.
Ein besonderer Wert bei Referenztypen ist null (bzw. das Äquivalent in anderen Sprachen) — er bedeutet “diese Variable zeigt gerade auf KEIN Objekt”. Primitive Typen kennen diesen Zustand normalerweise nicht (eine int-Variable hat immer einen konkreten Zahlenwert, nie “keinen Wert”). Der Versuch, auf ein Feld oder eine Methode eines null-Referenztyps zuzugreifen, führt zu einem der häufigsten Laufzeitfehler überhaupt (in Java als NullPointerException bekannt) — moderne Sprachen begegnen dem zunehmend mit eingebauten “Optional”/“Nullable”-Konzepten, die den Compiler zwingen, den null-Fall explizit zu behandeln, statt ihn übersehen zu können.
Ein weiterer praktischer Unterschied: Referenztypen werden in Sprachen mit automatischer Speicherverwaltung vom Garbage Collector verwaltet — ein Objekt bleibt im Speicher, solange irgendeine Referenz darauf existiert, und wird erst entfernt, wenn keine Variable mehr darauf zeigt. Primitive Werte dagegen liegen meist direkt und kurzlebig auf dem Aufrufstapel und benötigen diese Verwaltung nicht.