Veo que ya ha aceptado una respuesta, pero me gustaría añadir mi opinión, ya que creo que puedo ser de ayuda aquí.
La diferencia entre List<Animal>
y List<? extends Animal>
es la siguiente.
Con List<Animal>
, ya sabes lo que tienes es definitivamente una lista de animales. No es necesario que todos ellos sean exactamente 'Animales'; también podrían ser tipos derivados. Por ejemplo, si tiene una Lista de animales, tiene sentido que una pareja pueda ser Cabra, y algunos de ellos Gatos, etc. ¿Verdad?
Por ejemplo, esto es totalmente válida:
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
Por supuesto, la siguiente sería no ser válida:
aL.peek().meow(); // we can't do this, as it's not guaranteed that aL.peek() will be a Cat
Con List<? extends Animal>
, estás haciendo una declaración acerca el tipo de la lista que está tratando.
Por ejemplo:
List<? extends Animal> L;
Esto es en realidad no una declaración de tipo de objeto L puede mantener. Es una afirmación sobre los tipos de listas a las que L puede hacer referencia.
Por ejemplo, podríamos hacer esto:
L = aL; // remember aL is a List of Animals
Pero ahora todo el compilador sabe sobre L es que se trata de un Lista de [ya sea animal o un subtipo de Animal] s
Así que ahora lo siguiente no es válido:
L.add(new Animal()); // throws a compiletime error
Debido a que por lo que sabemos, L podría ser hacer referencia a una lista de las cabras - a wh No podemos agregar un Animal.
He aquí por qué:
List<Goat> gL = new List<Goat>(); // fine
gL.add(new Goat()); // fine
gL.add(new Animal()); // compiletime error
En lo anterior, estamos tratando de echar un animal como una cabra. Eso no funciona, porque ¿qué pasa si después de hacer eso tratamos de hacer que Animal haga un "cabezazo", como lo haría una cabra? No necesariamente sabemos que el Animal puede hacer eso.
+1 Para el enlace de la wikipedia. – helpermethod
En su primer ejemplo, obtendría un error de compilación en lugar de un error en tiempo de ejecución si pasa una lista a una lista –
@DonLi: De hecho. Es por eso que uso el [segundo condicional] (https://en.wikipedia.org/wiki/English_conditional_sentences#Second_conditional): * "Si ** se te permitió ** ..." *, es decir, en el escenario hipotético de que el compilador consideró 'List' como un subtipo de 'List '. –
Heinzi