Generics is applied in
java for the compile time type safety.during your code compilation compiler knows that list has a type List<? super C>.the captured types for"? super C" is "C" itself,class Object,class B and the class A.so for the compiler List<? super B> can be List<Object>,List<A>,List<B>,List<C>.so these capturing will make a compiler to think that List can have any of these types.during a time you are trying to add instance of class B to the list,compiler is simply thinking that list can be List<C>,List of C,and object of class B does not hold is a relationship with class C.
→B
is ais not a C.
you may be thinking that the parametric type of object on right hand side:
"List<? super C> list = new ArrayList<B>()" will help the compiler to infer that List is a list of B.but it will do no favor to compiler because object will be created during a runtime and during run time the generic information is not available(deleted after compilation).
so compiler can only infer the type from the type of the reference variable.indeed you can only add instance of C or null to this list.so make it a point that List<? super E> is a consumer of "E" type instances.
Hope it helps!
Kind regards,
praveen.