给定类型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>**的子类型

请让我知道这是否不够表达。谢谢:)

10-01 20:11
查看更多