This could be a very stupid question, however I don't understand why the compiler complains and compiles.
I have two very simple classes:
class A {
}
class B extends A {
}
Now the codes:
//block1
List<A> list = new ArrayList<>();
list.add(new A()); //ok
list.add(new B()); //ok
//block2
List<? extends A> extendList= new ArrayList<>();
extendList.add(new A()); //not ok, why?
extendList.add(new B()); //not ok, why?
//block3
List<? super A> superList = new ArrayList<>();
superList.add(new A()); //ok
superList.add(new B()); //ok. why?
The block1 I know why it worked.
The block2, I have <? extends A>
, as I understood, the list is gonna accept objects with type A
or subType of A
, for example B
. Why both add()
lines failed? with error:
Error: no suitable method found for add(A)
method java.util.Collection.add(capture#1 of ? extends A) is not applicable
(argument mismatch; A cannot be converted to capture#1 of ? extends A)
method java.util.List.add(capture#1 of ? extends A) is not applicable
(argument mismatch; A cannot be converted to capture#1 of ? extends A)
The block3, I have <? super A>
, as I understood, the list is gonna accept objects with type A
or superType of A
, B
is a subType of A
, why add(new B())
compiles?
I think I could have misunderstanding of the super
and extends
keywords, I did some google, however my doubt is still there.
A sentence from oracle generic tutorial: (https://docs.oracle.com/javase/tutorial/java/generics/upperBounded.html)
The term List<Number> is more restrictive than List<? extends Number>
because the former matches a list of type Number only, whereas the
latter matches a list of type Number or any of its subclasses.