给定类型List<?>
,List<Object>
,List<? super Number>
,List<Number>
,List<Integer>
和List<? extends Number>
,我试图理解它们的层次结构。
我知道List<Integer>
并不是List<Number>
的子类型,尽管Integer
确实是Number
的子类型,所以我认为它是List<? extends Number>
的子类型。
但是从直觉上来说List<? extends Number>
似乎是List<Number>
的子类型,这使得List<Integer>
毕竟是List<Number>
的后代,正如我的想法所示:
因此,如果一个类型是另一个的派生而不是直接派生的,它是否仍然是其祖先的子类型(或者我在图中是错误的)?这个练习也让我对?
与Object
有点困惑...实际上,看起来我可能将List<Object>
和List<? super Number>
混在一起了。我猜最大的问题之一是,“一切都是Object
...还是所有东西都是?
?”还是两者都没有?
最佳答案
List<Integer>
不是List<Number>
的子类型的原因。
让我们只考虑List<Number>
接受List<Integer>
(实际上是行不通的)的情况。
List<Integer> listI =new ArrayList<Integer>();
List<Double> listD = new ArrayList<Double>();
method(listI);
method(listD);
并且您有一个以
List<Number>
作为参数的方法。 public void method(List<Number> list) {
list.add(new Double()); // would fail if you pass an List<Integer> as Integer is not a super type of Integer.
list.add(new Integer()); //would fail if you pass an List<Double> as Double is not a subtype of Integer
}
因此,如果您声明为
List<number>
的方法参数接受List<Double>
,并且您尝试将整数添加到Double 的列表中,这是错误的,因为 Double 是而不是的超类型,因此子类型List<Number>
。现在考虑相同的场景,其中
List<Integer>
是方法参数而不是List<? extends Number>
public void method(List<? extends Number> list) {
// list.add(new Double());
// list.add(new Integer());
}
现在您将
List<Number>
传递给此方法。如果它接受它,并且您尝试将List<Integer>
添加到Integers 的列表中。 BOOM ...您刚刚在整数列表中添加了 Double 。给出一个非正式示例。将动物超型与猫和狗视为亚型。
现在,您有了一个接受
Double
的方法,并且将狗传递给此方法。然后在该方法中尝试添加 Cat 。它为您的狗添加了错误的类型(CAT),因此<? extends Animal>
不是**List<Dog>**
的子类型请让我知道这是否不够表达。谢谢:)