2010-01-07 32 views
5

¿Puede alguien decirme por qué esto da un error de compilación? No veo por qué el molde a A en el segundo bucle for causa cadenas() para devolver una Lista de objetos general.Comportamiento extraño con el método parametrizado en la clase abstracta

import java.util.ArrayList; 
import java.util.List; 

public class E { 

    public static void main(String[] args) { 
     for (String s : new D().strings()) { 
      System.out.println("s = " + s); 
     } 
     for (String s : ((A) new D()).strings()) { 
      System.out.println("s = " + s); 
     } 
    } 

    static class D extends A<C> { 
    } 

    static abstract class A<T extends B> { 
     List<String> strings() { 
      return new ArrayList<String>() {{ 
       add("Foo"); 
       add("Bar!"); 
      }}; 
     } 
    } 

    static class B { 
    } 

    static class C extends B { 
    } 
} 

¿Es esto una peculiaridad de Generics?

Gracias, Kristian

Respuesta

7

En la línea:

for (String s : ((A) new D()).strings()) { 

Estás convertir al tipo de prima A, por lo que se pierde la información de tipo de argumentos allí. En Java, cualquier método o campo de uso en un tipo sin procesar también daría como resultado un tipo sin procesar (incluso si toda la información parametrizada está disponible), bien en bruto o no parametrizado técnicamente. Por lo tanto, A.string() se ve como el tipo sin procesar List en lugar de List<String>.

Como el JSL especifica en Section 4.8:

El tipo de un constructor (§8.8), método de instancia (§8.8, §9.4), o no estático campo (§ 8.3) M de un crudo el tipo C que no se hereda de sus superclases o superinterfaces es la eliminación de su tipo en la declaración genérica correspondiente a C. El tipo de un miembro estático de un tipo sin procesar C es el mismo que su tipo en la declaración genérica correspondiente a C.

+3

Eso es realmente interesante. Eso explica por qué si lanzas a A en lugar de solo A, funciona. En ese caso, todavía estás usando una clase escrita. – Shaun

+0

+1 Gracias por esta gran respuesta. Eliminé mi propia respuesta, que no fue tan buena como esta. – KLE

+0

@Shaun, yup. ¡Parcialmente, es cuestión de molestarlo para evitar el uso de tipos crudos! – notnoop

Cuestiones relacionadas