这个Java输入层次结构是否正确?

时间:2012-11-17 22:43:37

标签: java object wildcard subtyping

鉴于类型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>的后代,正如我对它的看法所示:

enter image description here

所以,如果一个类型是另一个类型的后代,而不是直接类型,它仍然是它的祖先的子类型(或者我在图中是错的)?这个练习让我对?Object有点混淆......实际上,看起来我可能会混淆List<Object>List<? super Number>。我想其中一个最大的问题是,“一切都是Object ......还是一切都是??”或两者......或两者都没有?

1 个答案:

答案 0 :(得分: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>,并且您尝试将整数添加到列表中的。这是错误,因为 Double 不是整数的超类型,因此List<Number>不是子类型List<Integer>。< / p>

现在考虑List<? extends Number>是方法参数而不是List<Number>

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

现在您将List<Integer>传递给此方法。如果它接受了,您尝试将Double添加到整数列表 BOOM ...您刚刚将 Double 添加到整数列表

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

的子类型

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