The following code does not give any error :
List<A> l = new LinkedList<A>();
l.add(new B()); // B extends A
Then why does the below give error:
List<B> l = new LinkedList<B>();
List<A> l1 = l;
The following code does not give any error :
List<A> l = new LinkedList<A>();
l.add(new B()); // B extends A
Then why does the below give error:
List<B> l = new LinkedList<B>();
List<A> l1 = l;
B extends A does not mean List<B> extends List<A>. Assigning sub type collection to parent type will make it not type safe.
List<B> ListB = new LinkedList<B>();
List<A> ListA = ListB ; // Suppose you can compile it without error
ListA.add(new C()); // You can put C into ListA if C extends A
B b = ListB.get(0); // Then when you retrieve from ListB, you get a C, not type safe!
You need a wildcard to guarantee type safe and make it compile:
List<B> ListB = new LinkedList<B>();
List<? extends A> ListSubA = ListB ;
ListSubA.add(new C()); // Compile error, a wildcard can prevent user putting C into it
ListB.add(new B()); // You can only add new element by ListB
B b = ListB.get(0); // Type safe
It is explained here - https://docs.oracle.com/javase/tutorial/java/generics/inheritance.html
Basically List<A> is treated as a separate (not related in any way) type from List<B> so when you declare a reference of type List<A> it cannot point to an object of type List<B>.
There is a nice discussion here - Is List<Dog> a subclass of List<Animal>? Why are Java generics not implicitly polymorphic?