Can you please explain why it is possible to do:
import java.util.ArrayList;
import java.util.List;
public class Covariance {
class A {
}
class B extends A {
}
class C extends A {
}
public void testSmth() throws Exception {
List<? extends A> la = new ArrayList<A>();
A a = la.get(0);
// la.add(new B()); - doesn't compile
List<? super B> lb = new ArrayList<A>();
// lb.add(new A()); - doesn't compile
lb.add(new B());
Object object = lb.get(0);
}
}
I don't understand, why it is not possible to add something to covariant list la, but it's still possible to add B to contravariant list lb - but not A to lb.
From my point of view, it should be possible to add everything extending A to List. I can see the only reason of not doing that because it is easy to add C to list of B, like
List<B> lst = new ArrayList<B>();
List<? extends A> lstB = lst;
lstB.add(C); // this is valid for <? extends B> but list lst would contain instance of B.
Probably the same is true for contravariance, e.g
List<B> lst = new ArrayList<B>;
List<? super C> lstC = lst;
lstC.add(new C());
Object obj = lstC.get(0);
What I don't understand - why it is not possible to do
B b = lstC.get(0);
It is obvious that on this stage super of C would be class B - Java doesn't allow multiple inheritance.
Also why it prohibits
lstC.add(new B());
it's not clear for me.
To understand what's going on with the super keyword, consider the following:
import java.util.ArrayList;
import java.util.List;
public class Covariance {
class A {
}
class B extends A {
}
class C extends A {
}
class D extends C {}
public void testSmth() throws Exception {
List<? super D> ld = new ArrayList<C>();
}
}
Hopefully this illustrates that ld can be a List of any super type of D, even one that be a subclass of A.
consider
List<? extends A> la = new ArrayList<C>();
it's a list of C. if we could add B to it, that would violate the list type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With