Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
public static void main(String[] args) {
List<String> strList = new ArrayList<String>();
List<Integer> intList = (List) strList;
strList.add("bla");
// es wird bla ausgegeben, obwohl es List<Integer> ist
System.out.println(intList.get(0));
// ClassCastException
int a = intList.get(0);
}
So gesehen sind eher brutale, typ-unsichere casts mit Vorsicht zu genießen.
Generics können schon kompliziert werden, wenn man selbst eine API zur Verfügung stellen will, die Generics sinnvoll anbietet. Aber... OHNE Generics müßte man da noch viel vorsichtiger sein... :bahnhof:
Generics machen den Code sicherer und manchmal eleganter, allerdigs oft auch komplexer.
Aus Kompatibilitätsgründen unterstützt Java Raw-Types, was die zusätzliche Sicherheit durch Generics unter Umständen unterhöhlt.
Praktische Probleme ergeben sich daraus, dass Generics in Java zur Laufzeit nicht mehr vorhanden sind (type erasure), man also z.B. Probleme hat, ein Array von T zu erzeugen - [c]new T[42][/c] geht jedenfalls nicht. Oft kann man solche Probleme durch Übergabe von Class-Objekten lösen, wenn auch nicht sonderlich bequem.
Es gibt weitere Probleme mit der Implementierung von Generics in Java. Manchmal kann man z.B. einen "duplicate Method" Compilier-Fehler bekommen, obwohl man nur eine Methode dieses Namens hat. Die zweite wurde als "Brückenmethode" von Compiler eingefügt.
Dann gibt es noch Varianzen, die in Java über Wildcards ausgedrückt werden. Einer Variablen vom Typ
Code:
List<Hund>
kann auch nur eine
Code:
List<Hund>
zugewiesen werden, sonst nichts (Invarianz). Einer Variablen vom Typ
Code:
List<? extends Hund>
kann auch eine
Code:
List<Mops>
zugeweisen werden (Covarianz) und einer
Code:
List<? super Hund>
auch eine
Code:
List<Tier>
(Contravarianz). Das Problem ist, dass das wirklich notwendig ist, damit das Typsystem sicher ist, und dass viele Programmierer sich damit nicht beschäftigen - und sich dann wundern, dass sie einen
Code:
Hund
aus einer
Code:
List<? extends Hund>
lesen können, aber keinen hinzufügen.
Als Sahnehäubchen sei noch das CRTP erwähnt, ein Trick, bei dem die generische Signatur wie bei der Enum-Klasse aussieht: [c]class Enum<E extends Enum<E>>[/c]. Das ist die einzige sichere Möglichkeit in Java, in einer Oberklasse Methoden unter Verwendung des aktuellen Typs zu definieren. Z.B. implementiert
Code:
Enum
nicht
Code:
Comparable<Enum>
(wodurch man beliebige enums miteinander vergleichen dürfte), sondern
Code:
Comparable<E>
, wobei
Code:
E
der aktuelle Untertyp von
Code:
Enum
ist, also nur enum-Werte einer gemeinsamen Klasse untereinander verglichen werden können. Dieser Trick bringt einige Einschränkungen mit sich und ist ziemlich unhandlich.
Generics richtig zu verwenden ist schwierig, und Javas Implementierung hat Ecken und Kanten. Prinzipiell sind sie aber ein nützliches Hilfsmittel.