if you have <? extends A>
then at this point compiler does not know what is the subclass of A
that is getting used. So it's not safe to add any object to collection except null
.
You can't add any object to List<? extends T>
because you can't guarantee what kind of List it is really pointing to, so you can't guarantee that the object is allowed in that List. The only "guarantee" is that you can only read from it and you'll get a T
or subclass of T
.
List<? extends Number>
can be implemented by three:
List<? extends Number> list = new ArrayList<Number>();
// Number "extends" Number
List<? extends Number> list = new ArrayList<Integer>();
// Integer extends Number
List<? extends Number> list = new ArrayList<Double>();
// Double extends Number
So if it is new ArrayList<Double>()
and you are adding integer
so it's an error, so it's safe for compiler to restrict the access to only reading no adding.
And adding is also safe because we know the parent class hence we can assign any child class to parent class reference as below:
Parent p = new Child();
//this is safe
hence in List<? extends Number>
we know all the elements inside the collection are somehow extending Number
hence we can read it because we can assign an instance of child class to parent class reference.