📦 1. Das Konzept von Generics & Type Erasure
Vor Java 5 speicherten Datenstrukturen lediglich Object. Fehler durch inkompatible Datentypen wurden erst zur Laufzeit als ClassCastException sichtbar. Mit Generics prüft der Java-Compiler Typen bereits zur Compile-Zeit strikt ab.
└──> [JVM Bytecode: Autocast zu String ohne Overhead]
public class Box<T> {
private T content;
public Box(T content) {
this.content = content;
}
public T getContent() {
return this.content;
}
}
// Verwendung:
Box<String> box = new Box<>("Java 21");
String val = box.getContent(); // Kein Cast (String) nötig!
🛡️ 2. Bounded Types & das PECS-Prinzip
Manchmal muss ein generischer Typ bestimmte Eigenschaften besitzen – zum Beispiel vergleichbar sein oder eine Zahl repräsentieren. Hierfür nutzen wir Bounded Type Parameters:
<T extends Number>)
Ermöglicht den Zugriff auf Methoden wie doubleValue().
<T extends Comparable<T>>)
Garantiert, dass Elemente per compareTo() sortierbar sind.
? extends T / ? super T)
Producer Extends, Consumer Super für maximale API-Flexibilität.
// PECS: Kopieren von einer Quelle (Producer) in ein Ziel (Consumer)
public static <T> void copy(List<? extends T> src, List<? super T> dest) {
for (T item : src) {
dest.add(item);
}
}
Stell dir ein Containersystem vor: Ein Container Box<T> kann beliebige Frachtstücke transportieren. Die Frachtschranke (<T extends Gefahrengut>) stellt sicher, dass nur zertifizierte Güter in den Spezialtransporter geladen werden.
PECS: Wer Fracht nur entlädt (Producer), benötigt mindestens die Form ? extends Fracht. Wer Fracht aufnimmt (Consumer), muss Container für ? super Fracht bereitstellen!
📑 3. Cheat-Sheet: Generics in Java
| Syntax / Muster | Beispiel | Bedeutung & Enterprise-Einsatz |
|---|---|---|
class Box<T> |
Box<Customer> b; |
Generische Klasse mit Typparameter T |
<T extends B> |
<T extends Comparable<T>> |
Upper Bound: T muss Subtyp von B sein |
List<? extends T> |
List<? extends Number> |
Read-Only Producer: Liefert Instanzen von T |
List<? super T> |
List<? super Integer> |
Write-Only Consumer: Akzeptiert Instanzen von T |
List<?> |
int size(List<?> l) |
Unbounded Wildcard: Unbekannter Typ für generische Operationen |
🧠 Diagnostischer Selbst-Check
Überprüfe dein Verständnis von Sprach-Features, Speicherverwaltung und Enterprise-Architektur, bevor du den Code in der Web-IDE schreibst.
🎯 Aufgaben & Checkliste in Aufgabe.java
Producer Extends, Consumer Super: Wenn du Werte aus einer Liste entnimmst (Lesen), nutze ? extends. Wenn du Werte in eine Liste hineinsteckst (Schreiben), nutze ? super!