为什么在Java泛型中不允许这种分配

时间:2020-02-19 13:15:51

标签: java generics

这是代码示例

public static ArrayList<? extends A> get(){
   return null;
}

public static void main(String[] args){
   ArrayList<A> test=get();//not allowed
}

由于A当然是任何? extends A的超类,所以为什么不允许代码段?

1 个答案:

答案 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())