Generics in Java: wozu sie dienen und wie man sie verwendet

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Generics in Java: wozu sie dienen und wie man sie verwendet



Generics (Generics) sind eine der wichtigsten Funktionen von Java, die in der Version J2SE 5.0 eingeführt wurden. Sie ermöglichen die Erstellung von Klassen, Schnittstellen und Methoden, die mit Datentypen arbeiten, die zum Zeitpunkt des Aufrufs angegeben werden. Anstatt separate Implementierungen für Integer, String und Double zu schreiben, schreiben Sie einen einzigen universellen Code. In diesem Artikel werden wir untersuchen, wozu Generics in Java dienen, wie man sie in der Praxis verwendet und welche Fallstricke man kennen sollte.



Wozu dienen Generics in Java?



Vor der Einführung von Generics verwendeten Entwickler Object, um beliebige Typen zu speichern. Das funktionierte, führte aber zu zwei ernsthaften Problemen:



  • Fehlende Typprüfung zur Kompilierzeit. Sie konnten versehentlich einen String anstelle eines Integer in eine Liste einfügen, und der Fehler zeigte sich erst zur Laufzeit des Programms.
  • Notwendigkeit expliziter Typumwandlungen. Jedes Mal beim Abrufen eines Elements aus einer Sammlung war eine Umwandlung erforderlich: (String) list.get(0). Das machte den Code umständlich und fehleranfällig.


Generics lösen beide Probleme. Sie ermöglichen es dem Compiler, die Korrektheit der Typen zu überprüfen und die Umwandlung automatisch durchzuführen. Betrachten wir ein einfaches Beispiel:



// Ohne Generics (alter Stil)List list = new ArrayList();list.add("Hello");String s = (String) list.get(0); // explizite Umwandlung nötig

// Mit GenericsList<String> list = new ArrayList<>();list.add("Hello");String s = list.get(0); // keine Umwandlung erforderlich


Der Code ist sicherer und lesbarer geworden. Ein Typfehler wird zur Kompilierzeit erkannt, nicht zur Laufzeit.



Wie man Generics verwendet: grundlegende Konstrukte



1. Generic-Klassen



Sie können eine Klasse definieren, die einen oder mehrere Typparameter akzeptiert. Am häufigsten wird ein einzelner Buchstabe verwendet: T (Type), E (Element), K (Key), V (Value).



public class Box<T> {    private T content;

public void put(T item) { this.content = item; }

public T get() { return content; }}

// VerwendungBox<String> stringBox = new Box<>();stringBox.put("Java");String value = stringBox.get(); // automatische Umwandlung


Der Parameter T wird bei der Objekterstellung durch den tatsächlichen Typ ersetzt. Der Compiler garantiert, dass in eine Box<String> kein Integer eingefügt werden kann.



2. Generic-Methoden



Methoden können ebenfalls generisch sein, selbst wenn die Klasse nicht generisch ist. Der Typparameter wird vor dem Rückgabetyp angegeben:



public class Utils {    public static <T> T getMiddle(T... args) {        return args[args.length / 2];    }}

// AufrufString middle = Utils.<String>getMiddle("A", "B", "C");// oder einfach: Utils.getMiddle("A", "B", "C") — der Compiler leitet den Typ ab


Generic-Methoden sind nützlich für Hilfsfunktionen, die mit verschiedenen Datentypen arbeiten.



3. Eingeschränkte Typen (Bounded Type Parameters)



Manchmal muss man einschränken, welche Typen eingesetzt werden können. Zum Beispiel, damit eine Methode nur mit Zahlen arbeitet:



public class Calculator {    public static <T extends Number> double sum(T a, T b) {        return a.doubleValue() + b.doubleValue();    }}

// Funktioniert mit Integer, Double, Float usw.double result = Calculator.sum(5, 10); // 15.0


Das Schlüsselwort extends bedeutet, dass T ein Untertyp der angegebenen Klasse sein muss (oder eine Schnittstelle implementieren muss).



Wildcards: unbekannte Typen



Wildcards (Platzhalter) werden verwendet, wenn der genaue Typ unbekannt oder unwichtig ist. Sie werden durch das Fragezeichen ? gekennzeichnet. Es gibt drei Arten: