这是代码示例
public static ArrayList<? extends A> get(){
return null;
}
public static void main(String[] args){
ArrayList<A> test=get();//not allowed
}
由于A
当然是任何? extends A
的超类,所以为什么不允许代码段?
答案 0 :(得分:3)
您绕错了路; ArrayList<A>
可分配给ArrayList<? extends A>
,但是您正在尝试将ArrayList<? extends A>
分配给ArrayList<A>
。
实际上,List<? extends A>
是List<A>
的超类型,而不是子类型;使用REPL:
> List<A> list = new ArrayList<? extends A>();
Error:
unexpected type
required: class or interface without bounds
found: ? extends A
> List<? extends A> list = new ArrayList<A>();
[]
因此您的代码就像String s = new Object();
,而不是Object s = new String();
。
好,为什么List<? extends A>
不能分配给List<A>
?答案在Liskov substitution principle中。 List<A>
可以做List<? extends A>
做不到的事情,例如.add(new A())
:
> List<A> listA = new ArrayList<>();
[]
> listA.add(new A());
true
> List<? extends A> listExtendsA = new ArrayList<B>(); // B is a subclass of A
[]
> listExtendsA.add(new A());
Error:
incompatible types: A cannot be converted to capture#2 of ? extends A
这很有道理,因为您不应将A
的实例添加到List<B>
中。另一方面,List<A>
可分配给List<? extends A>
,因为List<A>
可以完成List<? extends A>
可以做到的一切。
实际上,List<? extends A>
不能做太多;例如,您甚至都无法.add(new B())
。