Ich habe gelesen, dass seit Java 7 das Erstellen von Collections mit der Angabe des Typs auf der rechten Seite wie in der ersten Anweisung ein schlechter Stil ist, da der Compiler den Typ von der linken Seite her ableiten kann.
%Vor%Meine Frage ist, wenn die Liste so initialisiert wird, findet der Compiler den Typ nicht und ich bekomme eine ungeprüfte Warnung:
%Vor% Der Compiler leitet den Typ nicht ab, weil Sie einen rohen ArrayList
instanziieren. Aber es ist schlau genug, um Sie zu warnen, dass es bei der Arbeit mit diesem (Roh-) Objekt Probleme geben könnte.
Es ist wichtig, den Grund für diese Warnung zu erwähnen. Aufgrund der Art Löschung , die Parameterinformationen ( <Integer>
) über die List
ist zur Laufzeit komplett verschwunden, wenn die Variable Elemente vom Typ Object
enthalten würde. Betrachten Sie dieses Snippet:
Dieses Snippet wird kompiliert, generiert jedoch nur wenige Warnungen. Mit einer unformatierten Liste ( rawList
) können Sie der Liste einen beliebigen nicht-primitiven Typ hinzufügen, einschließlich String
, Double
usw. Wenn Sie diese Auflistung einer Liste zuweisen, für die festgelegt ist nur Ganzzahlen, dann ist das ein Problem. Zur Laufzeit erhalten Sie ClassCastException
, wenn Sie versuchen, ein Element aus dem intList
zu holen, das ein Integer
sein soll, aber in Wirklichkeit ist ein String
oder etwas anderes.
Lange Rede kurzer Sinn - nicht Rohtypen mit Generika mischen!
In Ihrem Fall würde der Compiler möglicherweise den Typ abgeleitet haben, wenn Sie den Diamanten verwendet haben:
%Vor%Weil Sie die spitzen Klammern vergessen haben (Diamantoperator).
%Vor%Dies ist syntaktisch äquivalent zu
%Vor%aber anders als
%Vor%Im 3. sagen Sie, dass die rechte Seite ein raw-Typ ist, was bedeutet, dass die ArrayList jedes Objekt (nicht nur Integer) enthalten kann. Generics sind nur Kompilierzeit und werden in Save Type Casts kompiliert.
Aus Ссылка :
Beachten Sie, dass Sie die automatische Typrückmeldung bei generischen Funktionen nutzen können Klasseninstanziierung, müssen Sie den Diamanten angeben. [...] Der
HashMap()
-Konstruktor bezieht sich nicht auf denHashMap
rohen Typ DerMap<String, List<String>>
-Typ.
Sie können den Diamantoperator verwenden, um den Typ aus der Deklaration zu ermitteln, wie in JLS (§ 15.9) ,.
%Vor%Ein Klasseninstanzerstellungsausdruck gibt eine Klasse an, die instanziiert werden soll, möglicherweise gefolgt von Typargumenten (§4.5.1) oder einer Raute ("& lt; & gt;"), wenn die instanziierte Klasse generisch ist (§8.1.2) , gefolgt von einer (möglicherweise leeren) Liste von tatsächlichen Wertargumenten für den Konstruktor.