3.1 KiB
Generizität
Grundlagen
Durch Generizität können wir Typen, Klasse und Methoden parametrisieren. Der genutzte Typ wird dann zur Laufzeit übergeben.
Genutzt wird dieses Sprachkonzept z.B. im Collection Framework.
// Deklaration
class Test<T> {
public T gibHer(T type) { return type; }
}
// Benutzung
Test<String> test;
String result = test.gibHer(test);
Raw Types
Der Java-Compiler entfernt alle generischen Parameter und arbeitet dann auf den Raw Types. Dieser Vorgang wird Type Erasure genannt. Das führt zu Einschränkungen zur Laufzeit:
- Generische Klassen können keine statischen Felder haben
- Es können keine Instanzen aus generischen Typen erzeugt werden
- Es kann kein
instanceof
für generische Typen genutzt werden - ... (vollständige Liste auf der Java-Website)
Subtyping und Vererbung
Stehen zwei Typen in einer Subtyp-Beziehung (class Dreieck extends Form
) bedeutet das nicht, dass auch die parametrisierten Typen in einer Verbindung stehen.
// Deklaration
class FlaechenVerarbeiter {
public void verarbeiteFlaechen(List<Form> liste) {
}
// Benutzung
Dreieck dreieck = new Dreieck();
Verarbeiter verarbeiter = new Verarbeiter();
verarbeiter.verarbeiteFlaechen(dreieck); // Geht das?
Wildcards
Werden genutzt um beliebige generische Type als Parameter, Feld, lokale Variable oder Rückgabetypen zu deklarieren.
Benutzt wird dieses Sprachkonzept wenn man z.B. auf Collections arbeiten will:
class ListenSchreiber {
public void schreib(List<?> liste) {
for (Object elem: list) {
System.out.println(elem);
}
}
}
Warum wird hier nicht der Parameter-Typ List<Object>
genutzt?
Lower Bounds
Beschränkt den Wildcard Typen nach unten. Dafür wird das Schlüsselwort super
verwendet.
// Hierarchie Object -> Number -> Integer
class IntegerSammler {
public void schreib(List<? super Integer> liste) {
for (int i = 0; i <= 10; i++) {
liste.add(i);
}
}
}
Welche Typen akzeptiert der Compiler für den Parameter liste
?
Upper Bounds
Beschränkt den Wildcard Typen nach oben. Dafür wird das Schlüsselwort extends
verwendet.
// Hierarchie Object -> Number -> Integer
// -> Double
class Sortierer {
public void sortiere(List<? extends Number> liste) {
// Ein cleverer Sortieralgorithmus,
// der mit Vergleichoperatoren funktioniert.
}
}
Welche Typen akzeptiert der Compiler für den Parameter liste
?
Aufgaben
- Wann benutzt man
super
und wannextends
?- "Producers Extend, Consumers Super". Java Guidelines
extends
erlaubt das Aufrufen von Gettern,super
von Settern