Warum der Typ beim Verlassen des Generics-Operators nicht hergeleitet wird [duplizieren]

7

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%     
PKuhn 07.09.2015, 12:11
quelle

4 Antworten

12

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:

%Vor%

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%     
Konstantin Yovkov 07.09.2015, 12:14
quelle
9

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.

    
lschuetze 07.09.2015 12:13
quelle
7

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 den HashMap rohen Typ   Der Map<String, List<String>> -Typ.

    
sp00m 07.09.2015 12:15
quelle
2

Sie können den Diamantoperator verwenden, um den Typ aus der Deklaration zu ermitteln, wie in JLS (§ 15.9) ,.

  

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.

%Vor%     
Jordi Castilla 07.09.2015 12:15
quelle

Tags und Links