2017-03-23 2 views
1

Diese beiden Beispiele kompilieren nicht mit Oracle Java 8 JDK.Bounded Type Kompilierfehler in Java8

Der Fehler ist:

error: incompatible types: Object cannot be converted to Integer for (Integer i : foo.set)

Beispiel 1)

import java.util.Set; 

class Foo<T> 
{ 
    protected Set<Integer> set; 
} 

class Foo2 extends Foo 
{ 
    void doit() 
    { 
     for (Integer i : set) 
     { 

     } 
    } 
} 

Beispiel 2)

import java.util.Set; 

class Foo<T> 
{ 
    public Set<Integer> set; 
    public static void main(String[] args) 
    { 
     Foo foo = new Foo(); 
     for (Integer i : foo.set) 
     { 

     } 
    } 
} 

Ist es Bug oder Feature? Wie ich verstehen kann, arbeiten Generika nicht in Feldern vom Rohtyp.

+1

Merkwürdigerweise dies nicht kompiliert, wenn Sie 'foo' als typisierte Objekt konstruieren, auch wenn es nicht als 'Integer' eingegeben wird - sagen wir,' Foo foo = new Foo <>(); ' –

+1

Es ist möglich, weil Sie einen unformatierten Typ verwenden, alle Typinformationen werden in allen enthaltenen Feldern gelöscht, z 'Set ' wird 'Set'. –

+0

Warum verwenden Sie rohe Typen? –

Antwort

0

Es ist kein Fehler. Sie benötigen einen generischen Typ zu übergeben neue Instanz zu erstellen:

class Foo<T> 
{ 
    public Set<Integer> set; 
    public static void main(String[] args) { 

     Foo<Integer> foo = new Foo(); // changed code 

     for (Integer i : foo.set) 
     { 

     } 
    } 
} 
+0

Der Punkt war, dass der Typparameter 'T' nicht tatsächlich verwendet wird. Der Fehler war nicht beim Erstellen einer neuen Instanz, der Code in der Frage erstellt nur einen unformatierten Typ. –

+0

Ich verstehe das, ich habe bewusst rohen Typ gemacht. Rohtypen sind in Java nicht verboten. Und hier Set ist es nicht roher Typ, es ist in rohem Foo. Compiler ignoriert alle Feldtypen im Rohobjekt Foo. Es ist komisch. –

+0

@DenisPimenov ** Nicht. Je. Benutzen. Raw-Typen. ** Der einzige Grund, warum sie nicht verboten sind, ist die Rückwärtskompatibilität. Aber wenn ich neuen Code schreibe, verwende ** immer ** Typparameter. Siehe [diesen Beitrag] (http://stackoverflow.com/a/2770692/507738). Plus, selbst die [JLS, §4.8] (https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.8) gibt an, dass sie die Verwendung "nicht zulassen" könnte von rohen Typen "*. –