Typparameter T müssen Referenztypen sein, primitive Datentypen sind also nicht als Typparameter verwendbar.

class A<T> { // Klasse mit Typparameter, Deklaration!
 
    // parametrisiertes Feld:
    private T feld;
 
    // parametrisierter Konstruktur:
    A(T k) { feld = k; }
 
    // parametrisierter Methodenparameter:
    void set(T k) { feld = k; }
 
    // parametrisierter Rückgabewert:
    T m() { return feld; }
}

Vereinfachung von Generics

var a3 = new Auto<Benzin>(new Benzin());
// ist äquivalent zu:
var a3 = new Auto<>(new Benzin());

Einschränkung von Generics

Einschränkung durch extends

Der Typparameter muss entweder die Klasse Kraftstoff oder eine ihrer Unterklassen sein.

Auto<Rechteck> q7; // problematisch, wir wollen dass das Auto nur Kraftstoff und keine Rechtecke tanken kann
// Abhilfe schafft die Einschränkung:
class Auto<T extends Kraftstoff>

Wildcards

Ein Unbounded Wildcard ? erlaubt es, eine generische Klasse oder Methode mit einer unbekannten, aber spezifischen Art von Objekten zu arbeiten.

public static double sum(List<?> numbers) {
    // Die Funktion sum bekommt hier als Typ eine Klasse List, die einen generischen Typen hat. Dieser wird mit Hilfe der Wildcard generisch gelassen
}

Einschränkung von Wildcards

Wildcards kann man wie Generics auch einschränken:

? extends T  // T oder eine ihrer Unterklassen
? super T    // T oder eine ihrer Oberklassen