2012-03-28 1 views
0

Déclaration comme ceci:Pourquoi Wild Cards ne peut-il pas être utilisé dans une déclaration de classe et de méthode générique?

class A<X extends Number & List> { } 

est allowed.Whereas telle déclaration n'est pas autorisée.

class A<? extends Number & List> { } 

Y a-t-il une explication logique à propos des raisons pour lesquelles Java nous limite à cela?

& Quelle est la différence réelle entre

 <T extends Number> 
    & <? extends Number>? 
+1

Avez-vous réellement une classe qui étend 'Number' et implémente' List'? Ou est-ce qu'il étend 'Number' et implémente' Liste '? ou est-ce que X étend 'Number' et implémente' List '? Comment écririez-vous ce dernier sans déclarer le type 'X' quelque part? –

+0

Bon point - 'Number' et' List' ne sont pas vraiment des types que vous attendez de coexister comme ça. –

+0

@LouisWasserman: Même si elles coexistent comme ça, je voulais simplement vous faire remarquer que vous pourriez avoir besoin de la définition générique pour spécifier ce que votre liste contient. De toute façon, il vaut probablement mieux éviter le type brut. –

Répondre

1

Le point d'un paramètre de type entier comme T est que vous peut l'utiliser comme un type à l'intérieur de la classe. Que voudrait dire un joker? Si vous ne pouvez pas l'utiliser n'importe où, pourquoi avoir un paramètre de type?

3

Si vous avez utilisé <? extends Number & List>, alors vous ne seriez pas en mesure de faire quelque chose avec le paramètre de type. Ce serait complètement inutile.

De même, ? extends Number vous permet de traiter le cas particulier lorsque vous n'avez pas besoin de vous référer au type qui étend le numéro, et vous n'avez pas besoin de lui donner un nom.

0

Les déclarations génériques de classe et d'interface requièrent des paramètres de type, tels que T ou U.? est un caractère générique, mieux utilisé pour les paramètres de méthode qui sont eux-mêmes générique:

class Foo<T extends Number & List> { 
    void doStuff(List<T> items) { 
     // ... 
    } 

    void doMoreStuff(List<? extends OutputStream> streams) { 
     // ... 
    } 
} 

doStuff() indique qu'il veut fonctionner sur un List<T> où T est le paramètre de type de la classe Foo. Alors:

class Weird extends Number implements List { 
    // 
} 

Foo<Weird> f = new Foo<Weird>(); 
f.doStuff(...); // wants a List<Weird> 

Si nous avons appelé doMoreStuff() sur f, nous pourrions remettre quelque chose du type List<OutputStream>, List<FilterOutputStream>, List<ByteArrayOutputStream>, etc.

+0

Ne devriez-vous pas appeler 'doStuff()' sur Foo, pas bizarre? –

+0

Oups. Modification ... – pholser

Questions connexes