Vor kurzem wurde ich nach dem Sinn bzw. dem Einsatzzweck von <? super E> gefragt.
Bevor ich die Frage hier im Blog nochmals beantworte, kurz noch eine ganz kleine Einführung in Generics
Mit dem JDK 5.0 kamen die sogenannten Generics, mit denen Klassen und Methoden zusätzlich parametisiert werden können (Ähnlich wie die Templates in C++, mit dem Unterschied, dass keine neuen Klassen pro Parametertyp erstellt werden). Ziel der Generics ist die Lesbarkeit des Codes zu erhöhen und explizite Casts zu reduzieren. Allerdings kann die Verwendung von Generics auch sehr tückisch werden. Aber fangen wir mal einfach an (also ohne Generics):
Der folgende Codeausschnitt wird kompiliert und erzeugt zur Laufzeit eine ClassCastException. Unschön.
-
ArrayList intList = new ArrayList();
-
intList.add(new Double(2)); // Semantisch falsch, aber kein Fehler beim Kompilieren.
-
Integer integer = (Integer) intList.get(0); // Ups, ClassCastException zur Laufzeit
Ungefährlicher ist Codeausschnitt 2, da hier schon der Compiler den Fehler meldet:
-
ArrayList<Integer> intList = new ArrayList();
-
intList.add(new Double(2)) // Fehler zur Kompilierzeit
-
Integer integer = (Integer) intList.get(0);
Mit der Verwendung der Generics wird die ArrayListe parametisiert und erlaubt nur das Hinzufügen von Integer Objekten. Der Compiler unterbindet den fehlerhaften Aufruf und verhindert unliebsame
Überraschungen zur Laufzeit. Schön.
Morgen gibts schon weiter mit Teil 2: Wildcards. Da wirds etwas kniffliger.