Das Problem mit
List list = new LinkedList();
ist, dass auf der linken Seite der generische Typ List
verwendet wird, wohingegen auf der rechten Seite der raw Typ LinkedList
verwendet wird. Raw-Typen in Java existieren effektiv nur für die Kompatibilität mit Code vor Generics und sollten in neuem Code nie verwendet werden, es sei denn, es ist unbedingt erforderlich.
Angenommen, Java hätte von Anfang an Generics und hätte keine Typen wie LinkedList
, die ursprünglich erstellt wurden, bevor es Generics hatte, dann hätte es wahrscheinlich so gemacht, dass der Konstruktor eines generischen Typs automatisch seine Typparameter von der linken Seite der Zuweisung ableitet, wenn möglich. Aber das ist nicht der Fall, und es muss Raw-Typen und generische Typen aus Gründen der Abwärtskompatibilität unterschiedlich behandeln. Das führt dazu, dass sie eine etwas andere, aber gleichzeitig bequeme Methode zum Deklarieren einer neuen Instanz eines generischen Objekts benötigen, ohne die Typparameter erneut angeben zu müssen... den Diamantenoperator.
In Bezug auf Ihr ursprüngliches Beispiel von List list = new LinkedList()
erzeugt der Compiler eine Warnung für diese Zuweisung, weil er muss. Betrachten Sie dies:
List strings = ... // einige Liste, die einige Zeichenketten enthält
// Völlig legal, da Sie den Raw-Typ verwendet haben und jegliche Typüberprüfung verloren haben!
List integers = new LinkedList(strings);
Generics dienen dazu, einen Schutz zur Compile-Zeit gegen falsche Anwendungen zu bieten. Im obigen Beispiel bedeutet die Verwendung des Raw-Typs, dass Sie diesen Schutz nicht erhalten und bei der Ausführung einen Fehler erhalten werden. Deshalb sollten Sie keine Raw-Typen verwenden.
// Nicht zulässig, da die rechte Seite tatsächlich generisch ist!
List integers = new LinkedList<>(strings);
Der Diamantenoperator ermöglicht es jedoch, dass die rechte Seite der Zuweisung als echte generische Instanz mit denselben Typparametern wie die linke Seite definiert werden kann... ohne diese Parameter erneut eingeben zu müssen. Er ermöglicht es Ihnen, die Sicherheit von Generics mit fast demselben Aufwand wie bei der Verwendung des Raw-Typs beizubehalten.
Ich denke, das Entscheidende zu verstehen ist, dass Raw-Typen (ohne <>
) nicht genauso behandelt werden können wie generische Typen. Wenn Sie einen Raw-Typ deklarieren, erhalten Sie keinerlei Vorteile und Typüberprüfungen von Generics. Sie müssen auch bedenken, dass Generics ein allgemeiner Bestandteil der Java-Sprache sind... sie gelten nicht nur für die no-arg-Konstruktoren von Collection
n!
4 Stimmen
Beachten Sie, dass dies kein Problem darstellt, wenn Sie statische Fabrikmethoden verwenden, da Java Typenschlüsseleinschätzung bei Methodenaufrufen durchführt.
0 Stimmen
Wenn Sie die Warnung deaktivieren, ist sie tatsächlich nutzlos... :) wie für mich
4 Stimmen
Es wurde beantwortet, aber es befindet sich auch im Java-Tutorial (etwa in der Mitte der Seite): docs.oracle.com/javase/tutorial/java/generics/…
0 Stimmen
Schöner Artikel dazu auf dZone.
2 Stimmen
Meine Ansicht dazu ist, dass dies nur syntaktischer Zucker für List list = new LinkedList(); ist, also bleibt es generisch