1
votes

Hi i have a query in below code.

When i declare list of animals it allows me to put Cat() and Dog() in it as they both are animal and satisfy IS A relation ship.

Class Cat extends Animal{}
Class Dog extends Animal{}

List<Animal> list = new ArrayList<Animal>();
list.add(new Dog());//Code works fine
list.add(new Cat());//Code works fine

Now here is my question if ? extends means accept anything that is subclass of Animal, then why is following code not compiling.

List<? extends Animal> list = new ArrayList<Animal>();
list.add(new Dog());//Compilation fails 
list.add(new Cat());//Compilation fails 

Same question , why dog is not accepted here ?

List<? extends Animal> dogs1 = new ArrayList<Dog>();
dogs1.add(new Dog());//Compilation fails

Can some one explain this behavior ?

1
This is definitely a duplicate, someone will flag it. Basically, your List could be of any subclass of Animal. If it were a List<Dog> you wouldn't be able to add cats and vice versa. Because Java can't tell what it is, it doesn't allow you to add anything to itRobin Topper
@Kayaman That is a weird "duplicate"Robin Topper
Mods-Please check valid duplicate....:( else don't mark it as duplicateSachin Sachdeva

1 Answers

2
votes

A variable of type List<? extends Animal> can be assigned a List<Animal>, a List<Cat> or a List<Dog>. Some of these lists don't allow Dogs to be added to them, while others don't allow Cats.

The compiler validates the correctness of the list.add statements based on the compile time type of the list variable, not based on the actual object assigned to it in runtime. Therefore both list.add(new Dog()); and list.add(new Cat()); are not accepted.

If you wish to be able to add both Dogs and Cats, use a variable of type List<Animal>.

If you wish to only be able to add Dogs, use a variable of type List<Dog>.