Je vois que vous avez déjà accepté une réponse, mais je voudrais juste ajouter mon point de vue, car je pense que je peux être utile ici. La différence entre List<Animal>
et List<? extends Animal>
est la suivante.
Avec List<Animal>
, vous savez ce que vous avez est certainement une liste des animaux. Il n'est pas nécessaire que tous soient exactement 'Animal' - ils pourraient aussi être des types dérivés. Par exemple, si vous avez une liste d'animaux, il est logique qu'un couple puisse être des chèvres, et certains d'entre eux des chats, etc - non?
Par exemple ceci est tout à fait valable:
List<Animal> aL= new List<Animal>();
aL.add(new Goat());
aL.add(new Cat());
Animal a = aL.peek();
a.walk(); // assuming walk is a method within Animal
Bien sûr, ce qui suit ne pas valable:
aL.peek().meow(); // we can't do this, as it's not guaranteed that aL.peek() will be a Cat
Avec List<? extends Animal>
, vous faites une déclaration au sujet le type de liste vous avez affaire.
Par exemple:
List<? extends Animal> L;
Ceci est en fait pas une déclaration du type d'objet L peut tenir. C'est une déclaration sur les types de listes que L peut référencer.
Par exemple, nous pourrions faire ceci:
L = aL; // remember aL is a List of Animals
Mais maintenant tout le compilateur sait L est qu'il est une Liste des [animaux ou un sous-type d'animal] s
Alors maintenant, ce qui suit est pas valide:
L.add(new Animal()); // throws a compiletime error
Parce que pour tout ce que nous savons, l pourrait être une référence à la liste des chèvres - à des Wh Je ne peux pas ajouter un animal.
Voici pourquoi:
List<Goat> gL = new List<Goat>(); // fine
gL.add(new Goat()); // fine
gL.add(new Animal()); // compiletime error
Dans ce qui précède, nous essayons de jeter un animal comme une chèvre. Ça ne marche pas, parce que si après cela nous essayions de faire de cet Animal un 'headbutt', comme une chèvre? Nous ne savons pas nécessairement que l'animal peut le faire.
+1 Pour le lien wikipedia. – helpermethod
Dans votre premier exemple, vous obtiendrez une erreur de compilateur plutôt qu'une erreur d'exécution si vous passez une liste à une liste –
@DonLi: En effet. C'est pourquoi j'utilise le [second conditionnel] (https://en.wikipedia.org/wiki/English_conditional_sentences#Second_conditional): * "Si vous ** avez été autorisé ** ..." *, c'est-à-dire dans le scénario hypothétique que le compilateur considéré comme 'Liste' pour être un sous-type de 'Liste '. –
Heinzi