2011-06-07 4 views
3

Le code ci-dessous prend tout son sens - son ajout d'un type de type supertype de type T et le type S est définitivement un super type, alors pourquoi le compilateur refuse d'ajouter 'element' dans la collection?Méthode générique bornée ne compilant pas - pourquoi?

class GenericType<S,T extends S>{ 
    void add1(Collection<? super T> col ,S element){ 
     col.add(element); // error 
     // The method add(capture#9-of ? super T) in the type 
     // Collection<capture#9-of ? super T> is not applicable for the arguments (S) 
    } 
} 

Répondre

2

Collection<? super T> ne fait pas signifie « une collection qui peut contenir T et tout superclasse de celui-ci » - il est en fait impossible de formuler cette restriction. Qu'est-ce que cela signifie est "une collection qui ne peut contenir que des instances d'une classe spécifique qui est une super-classe de T" - en gros, il s'assure que vous pouvez ajouter un T à la collection.

La méthode peut être appelée avec un Collection<T>, mais vous voulez lui ajouter un S.

+0

Étant donné ce que vous dites, comment est donc cette autre déclaration de quelque chose qui ne * pas * l'utilisation générique (Collection au lieu de Collection )? – Bhaskar

+0

@Bhaskar: le caractère générique vous permet également d'appeler la méthode avec une collection ou une collection - tout ce que vous pouvez ajouter un T à. –

5

Thake exemple, si A <- B <- C<- signifie que est le supertype, alors si S = B et T = C vous ne pouvez pas ajouter une instance de S à une collection de T.

Un supertype de T peut être le supertype ou un sous-type d'un autre supertype de T (dans ce cas S).

+0

oui Je suis d'accord avec votre dérivation, mais le fait demeure que S est un supertype - alors pourquoi ce fait n'est-il pas jugé suffisant pour permettre cette addition? Je peux voir qu'autoriser cela conduira également à une exception d'exécution possible, est-ce parce que les concepteurs ont décidé d'éviter d'entrer dans de telles situations d'exécution? si vous, alors quelle est la différence entre Collection et Collection dans l'utilisation ci-dessus? – Bhaskar

+0

bonne réponse en effet, mais je dois le donner à Michael pour me permettre de le comprendre en prose. – Bhaskar

0

Vous essayez de placer un élément de type S dans une collection de type T. Les génériques ne sont pas polymorphes. Vous devez prendre connaissance de 2 problèmes ici. vous essayez de créer une collection de type concreteObject étend objet et ajoutez un objet Ainsi, lorsque vous avez

Car extends Vehicle{} 
ElectricCar extends Car{} 

que vous essayez de faire

Collection<? extends Car> collection; 
collection.add(new Vehicle()); 

Le deuxième problème réside dans le non-polymorphisme nature des génériques. Voir cette grande explication ->Is List<Dog> a subclass of List<Animal>? Why aren't Java's generics implicitly polymorphic?

2
new GenericType<Object,Integer>().add1(new ArrayList<Integer>(), ""); 
+0

+1 pour un exemple concret valide et dangereux. Bien qu'il puisse être plus clair que vous exercez le mot-clé «super» si vous avez passé dans un «ArrayList ». L'utilisation de 'ArrayList ' montre la faille la plus évidente dans le raisonnement de l'OP, en ce que 'List ' admet un 'List ' qui n'acceptera évidemment pas un super-type arbitraire de 'T'. –

+0

+1 pour le code concis et précis faisant ressortir le défaut – Bhaskar

Questions connexes