Interface Z{}
考虑上面声明的一个简单接口Z。
Class A{}
上面声明的一个简单的类A。
Class B extends A implements Z{}
Class B扩展了Class A并实现了接口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
}
}
上面测试类中的add方法有一个参数List,据我所知,我可以用类型为Z的List或类型为Z实现类的superclass的列表来调用它。
类B是Z的实现,但也是a的子类,因此类a满足上述条件。它是Z(类B(的实现类(B类(的超类。
所以,当我用ArrayList调用add((时,为什么它会给出一个错误。
假设这是add
的方法体。这编译得很好:
static void add(List<? super Z> list){
list.add(new Z() {}); // Fine.
}
此外,这编译得很好。
List<A> aaa= new ArrayList<>();
// ... Something.
A a = aaa.get(0);
现在,如果... Something
是:
add(aaa); // Compiler error!
如果编译器错误没有发生,会发生什么?A a = aaa.get(0);
行上的ClassCastException
,因为它是不是A
的Z
的某个子类的实例。
通过调用add((List) aaa)
来尝试它。
这就是为什么编译器会阻止你这么做。List<? super Z>
是一个列表,可以安全地向其中添加Z
或任何子类的实例。List<A>
是一个列表,可以安全地向其中添加A
、任何子类或null的实例;从列表中检索到的任何内容都将是A
、子类或null。Z
的某些实例不是A
的实例。