2010-01-07 7 views
5

Quelqu'un peut-il me dire pourquoi cela donne une erreur de compilation? Je ne vois pas pourquoi le cast à A dans la deuxième for-loop provoque des chaînes() pour retourner une liste générale d'objets.Comportement étrange avec la méthode paramétrée sur la classe abstraite

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 { 
    } 
} 

Est-ce une anomalie de Generics?

Merci, Kristian

Répondre

7

Dans la ligne:

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

Vous association au type cru A, de sorte que vous perdez des arguments de type d'informations là-bas. En Java, toute méthode ou champ d'utilisation sur un type brut conduirait également à un type brut (même si toutes les informations paramétrées sont disponibles) - bien brut ou non paramétré techniquement. Donc, A.string() est considéré comme le type brut List plutôt que List<String>.

Comme l'indique JSL dans Section 4.8:

Le type d'un constructeur (§8.8), méthode d'instance (§8.8, §9.4), ou d'un champ non statique (§8.3) M d'une première le type C qui n'est pas hérité de ses superclasses ou superinterfaces est l'effacement de son type dans la déclaration générique correspondant à C. Le type d'un membre statique d'un type brut C est le même que son type dans la déclaration générique correspondant à C.

+3

C'est vraiment intéressant. Cela explique pourquoi si vous lancez à A au lieu de juste A cela fonctionne. Dans ce cas, vous utilisez toujours une classe typée. – Shaun

+0

+1 Merci pour cette excellente réponse. J'ai supprimé ma propre réponse, qui n'était pas aussi bonne que celle-ci. – KLE

+0

@Shaun, yup. En partie, il s'agit de vous ennuyer afin d'éviter d'utiliser des types bruts! – notnoop

Questions connexes