Interface Z{}
Consider a simple interface Z as declared above.
Class A{}
A simple class A as declared above.
Class B extends A implements Z{}
Class B extends class A and implements interface Z
class Test{
static void add(List<? super Z>){}
public static void main(String[] args){
List<A> aaa= new ArrayList<>();
add(aaa); //Gives error here
}
}
The add method in above test class has a parameter List so as far as i know i can call it with alist of type Z or with a list of type super class of implementation class of Z.
class B is an implementation of Z but is also a child of A so class A satisfies the condition above .It is a super class of (class B) implementation class of Z(class B).
So when i call add() with an ArrayList why does it give an error.
Imagine this is the method body of add
. This compiles fine:
static void add(List<? super Z> list){
list.add(new Z() {}); // Fine.
}
Also, this compiles fine.
List<A> aaa= new ArrayList<>();
// ... Something.
A a = aaa.get(0);
Now, what if the ... Something
is:
add(aaa); // Compiler error!
What would happen if that compiler error didn't happen? A ClassCastException
on the A a = aaa.get(0);
line, because it's an instance of some subclass of Z
that's not A
.
Try it, by invoking add((List) aaa)
.
This is why the compiler stops you doing it. List<? super Z>
is a list to which it's safe to add instances of Z
, or any subclass. List<A>
is a list to which it's safe to add instances of A
, or any subclass, or null; and anything you retrieve from the list will be an A
, a subclass, or null. Some instances of Z
aren't instances of A
.