# 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. ```java // Deklaration class Test { public T gibHer(T type) { return type; } } ``` ```java // Benutzung Test 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](https://docs.oracle.com/javase/tutorial/java/generics/restrictions.html)) --- # 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. ```java // Deklaration class FlaechenVerarbeiter { public void verarbeiteFlaechen(List
liste) { } ``` ```java // 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: ```java class ListenSchreiber { public void schreib(List liste) { for (Object elem: list) { System.out.println(elem); } } } ``` Warum wird hier nicht der Parameter-Typ ``List`` genutzt? --- ## Lower Bounds Beschränkt den Wildcard Typen nach unten. Dafür wird das Schlüsselwort ``super`` verwendet. ```java // Hierarchie Object -> Number -> Integer class IntegerSammler { public void schreib(List 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. ```java // Hierarchie Object -> Number -> Integer // -> Double class Sortierer { public void sortiere(List liste) { // Ein cleverer Sortieralgorithmus, // der mit Vergleichoperatoren funktioniert. } } ``` Welche Typen akzeptiert der Compiler für den Parameter ``liste``? --- # Aufgaben 1) Wann benutzt man ``super`` und wann ``extends`` ? * "Producers Extend, Consumers Super". [Java Guidelines](https://docs.oracle.com/javase/tutorial/java/generics/wildcardGuidelines.html) * ``extends`` erlaubt das Aufrufen von Gettern, ``super`` von Settern