List<? super B> lsb = new ArrayList<A>(); Logical error in java?
We have:
class A{}
class B extends A{}
class C extends B{}
class D extends C{}
we can define Lists like:
List<? super B> lsb1 = new ArrayList<Object>();
//List<? super B> lsb2 = new ArrayList<Integer>();//Integer, we expect this
List<? super B> lsb3 = new ArrayList<A>();
List<? super B> lsb4 = new ArrayList<B>();
//List<? super B> lsb5 = new ArrayList<C>();//not compile
//List<? super B> lsb6 = new ArrayList<D>();//not compile
now we crate 开发者_Go百科some objects:
Object o = new Object();
Integer i = new Integer(3);
A a = new A();
B b = new B();
C c = new C();
D d = new D();
I will try to add this objects to List:
List<? super B> lsb = new ArrayList<A>();
lsb.add(o);//not compile
lsb.add(i);//not compile
lsb.add(a);//not compile
lsb.add(b);
lsb.add(c);
lsb.add(d);
Question:
Why when I define reference for List<? super B>
can I use new ArrayList<>();
which can have elements type of B, A, Object (I expected this), but when I add elements to this list can I add only objects with type B, C, D?
Explained beautifully here @ JavaRanch FAQs.
A List<? super B>
is a List
, whose exact component type is unknown. All the compiler knows is that the component type is B
, A
or Object
.
It could be a List<B>
.
If it is a List<B>
, you cannot add an element A
.
This is to prevent the following, which can happen with arrays:
String[] x = new String[10];
Object[] x2 = x;
x2[0] = 123; // not a String, compiles, but crashes at run-time
精彩评论