3

鉴于类型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>

在此处输入图像描述

那么,如果一个类型是另一个类型的后代,但不是直接的,它是否仍然是其祖先的子类型(或者我在图中只是错了)?这个练习也让我对?vs.有点困惑Object......实际上,看起来我可能有List<Object>并且List<? super Number>混淆了。我想最大的问题之一是,“‘一切’都是Object……还是一切都是…… ??” 或者两者都有……或者两者都没有?

4

1 回答 1

2

为什么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>并且您尝试将Integer添加到Double 列表中,这是错误的,因为Double不是Integer的超类型,因此不是子类型。List<Number>List<Integer>

现在考虑相同的场景,其中List<? extends Number>是方法参数而不是List<Number>

            public void method(List<? extends Number> list) {
                      // list.add(new Double()); 
                      // list.add(new Integer());       
               }

现在你将一个传递List<Integer>给这个方法。如果它接受它并且您尝试将一个添加DoubleIntegers 列表中BOOM ...您刚刚在 Integer 列表中添加了一个Double

举个非正式的例子。考虑以CatDog作为子类型的Animal超类型。现在,您有一个接受的方法,并将Dog传递给此方法。并在您尝试添加Cat的方法中。它向您的Dog添加了错误的类型(CAT),因此 不是 <? extends Animal>**List<Dog>**List<? extends Animal>

如果这不够表达,请告诉我。谢谢:)

于 2012-11-17T23:04:20.417 回答