2009-06-21 8 views
3

J'ai une classe définie comme ceci:Impossible d'appeler la méthode générique avec caractère générique

public class Test { 
    static <T> List<Class<T>> filter(List<Class<T>> input) { 
     // code here 
    } 

    public static void main(String[] args) { 
     List<Class<? extends Throwable>> list = 
      new ArrayList<Class<? extends Throwable>>(); 
     filter(list); 
    } 
} 

L'appel de méthode filter dans main donne l'erreur de compilation suivante:

The method filter(List<Class<T>>) in the type Test is not applicable for the 
arguments (List<Class<? extends Throwable>>) 

Je ne comprends pas pourquoi <T> ne lie pas à <? extends Throwable>. Y a-t-il des gourous génériques qui peuvent m'aider?

Répondre

4

Je crois que le problème ici est qu'il n'y a aucun type pour ? qui ferait. Considérons si, par simplicité, nous avons remplacé Class par AtomicReference.

static <T> void filter(List<AtomicReference<T>> input) { 
    T value = input.get(0).get(); 
    input.get(1).set(value); 
} 

Si l'input consistait en un AtomicReference<Integer> et un AtomicReference<String> nous serions en difficulté.

Le problème sous-jacent que les pointeurs vers des pointeurs en présence de polymorphisme est difficile. Sans génériques, nous pouvons simplement faire des vagues. Avec les génériques, nous devons réellement signifier quelque chose.

+0

Bel exemple. Ça commence à faire une lueur de sens. –

+1

La dernière ligne devrait être 'input.get (1) .set (value)' (je n'étais pas autorisé à faire 1 édition de char). – JHH

+0

@JHH Yup. Merci. –

4

Ah, les joies des signatures génériques.

Vous pouvez le corriger en déclarant que le paramètre:

static <T> List<Class<T>> filter(List<Class<? extends T>> input) { 
    // code here 
} 

Quant à savoir pourquoi, je ne suis pas sûr. Trop de problèmes de compilation avec les génériques sont résolus en essayant diverses choses jusqu'à ce que la ligne rouge disparaisse. Pas satisfaisant.

+1

de Might la peine de vérifier http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html – akarnokd

+0

qui corrige l'erreur lors de l'appel de la méthode (bien que je don ne comprends pas pourquoi), mais maintenant j'ai une erreur à l'intérieur de la méthode. Fondamentalement, j'ai un 'List >' qui contient le résultat, et je ne peux pas ajouter des entrées car 'Class ' ne peut pas être converti en 'Class '. Au moins, cela a du sens pour moi. J'ai changé la méthode pour retourner 'List >', ainsi, et cela compile. C'est bizarre, mais ça fonctionne. –

+0

Le livre "Java Generic and Collections" d'O'Reilly (http://oreilly.com/catalog/9780596527754/) est également un excellent investissement si vous voulez comprendre comment fonctionnent les génériques. – skaffman

0

vous pouvez aussi écrire principale comme ci-dessous:

public static void main(String[] args) { 
    List<Class<Throwable>> list = 
     new ArrayList<Class<Throwable>>(); 
    filter(list); 
} 
Questions connexes