Generics ermöglichen die Erstellung von Klassen, Schnittstellen und Methoden mit Typparametern, was die Typprüfung zur Kompilierzeit sicherstellt und hilft, ClassCastException zu vermeiden.
Wichtige Merkmale und Fallstricke:
new List<String>[10] — Kompilierfehler.T obj = new T();instanceof kann nicht mit parametrierbaren Typen verwendet werden: if(obj instanceof List<String>) — Fehler.? extends T — Kovariante (lesen), ? super T — kontravariant (schreiben).Beispiel:
// Kovariante Methode zum Lesen void printNumbers(List<? extends Number> numbers) { for (Number n : numbers) { System.out.println(n); } } // Kontravariate Methode zum Schreiben void addIntegers(List<? super Integer> list) { list.add(10); } }
Frage: "Was ist der Unterschied zwischen List<Object> und List<?>? Kann man ein beliebiges Objekt in List<?> einfügen?"
Antwort: Nein, in List<?> kann man nichts hinzufügen (außer null), da der Compiler nicht weiß, welcher Typparameter dort ist. In List<Object> kann man hingegen beliebige Objekte hinzufügen.
Beispiel:
List<?> list1 = new ArrayList<String>(); // list1.add("test"); // Kompilierfehler! List<Object> list2 = new ArrayList<>(); list2.add("test"); // OK
Geschichte
Ein Entwicklerteam versuchte, einen Cache basierend auf einem Array vom parametrierten Typ
T[]zu implementieren. Aufgrund der Typlöschung und der Unmöglichkeit, Arrays vom generischen Typ zu erstellen, funktionierte die Lösung nicht wie erwartet: es entstand ein ArrayObject[], was zu ClassCastException bei Laufzeit-Casts führte.
Geschichte
In einem der Mikrodienste versuchte ein Entwickler, einen Empfänger zu implementieren, der List<?> als Parameter verwendete, und versuchte, die Sammlung zu modifizieren. Dies führte zu einem Kompilierfehler und verzögerte den Release-Termin, da die Logik mit Berücksichtigung von PECS umgestaltet werden musste.
Geschichte
Im Projekt zur Integration mit einem externen System machte ein Entwickler einen Fehler, indem er eine Sammlung eines Typs durch eine andere über einen unbearbeiteten Raw-Type überschreibt: List list = new ArrayList<String>(), was zu ClassCastException und Abstürzen des Dienstes in der Produktion führte, als versucht wurde, die Elemente in andere Typen zu konvertieren.