List <! - ? - > List <integer>和List <number>的共同父项?

时间:2016-06-24 08:40:15

标签: java generics inheritance polymorphism

来自this Oracle tutorial

  

虽然IntegerNumber的子类型,但List<Integer>不是   List<Number>的子类型,事实上,这两种类型无关。

     

List<Number>List<Integer>的共同父母是List<?>

我的问题是关于第二句话。 我们如何说List<?>List<Number>List<Integer>的共同父母?

?代表一种未知类型,可能是任何引用类型。即使我在这里说?ObjectObjectIntegerNumber的共同父母并不意味着List<Object>变为List<Integer>List<Number>的共同父母。

5 个答案:

答案 0 :(得分:29)

您需要了解的背景不是IntegerNumber,而是 List 。假设您是创建List类的人,那么您将如何创建该类,以便它只支持特定类型的类。

是的,List类不会使用Object作为其类型,而是使用通配符?

正如documentation of WildCards所说

  

那么各种收藏品的超类型是什么?它是Collection<?>(发音为&#34;未知&#34的集合;)

同样的事情可以说是List。

  

那么各种列表的超类型是什么?它是List<?>(发音为&#34;未知列表&#34;)

答案 1 :(得分:12)

我们可以证明List<?>List<Number>List<Integer>的超类型。

来自JLS 4.10.2(强调我的):

  

给定泛型类型声明C&lt; F1,...,Fn&gt; (n> 0),参数化类型C<T1,...,Tn>直接超类型,其中Ti(1≤i≤n)是一种类型,全部如下:

     
      
  • ...

  •   
  • C<S1,...,Sn>,其中Si 包含 Ti(1≤i≤n)(§4.5.1)

  •   

C替换为Listn=1,我们知道List<?>List<Number>List<Integer> 的直接超类型如果 ?包含NumberInteger

我们可以证明? 包含 NumberInteger,因为来自JLS 4.5.1

  

通配符? extends Object等同于无界通配符?

并进一步:

  

类型参数T1被称为包含另一个类型参数T2,写成T2&lt; = T1,如果由T2表示的类型可证明是在以下规则的反身和传递闭包下由T1表示的类型集的子集(其中&lt;:表示子类型(§4.10)):

     
      如果T&lt;:S ,则
  • ? extends T&lt; = ? extends S   
  • ...
  •   
  • T&lt; = ? extends T
  •   

我们可以使用上述规则来证明Number&lt; = ?,因为Number&lt; = ? extends Number&lt; = ? extends Object = { {1}}。

答案 2 :(得分:5)

本教程是关于通配符的。所以他们想解释你何时以及如何使用它们。当您预读时,有示例代码:

List<? extends Integer> intList = new ArrayList<>();
List<? extends Number>  numList = intList;  // OK. List<? extends Integer> is a subtype of List<? extends Number>

如果?IntegerNumber的共同父级,则您只能执行此分配。 我认为在与通配符和泛型的关系中,可以这样说:

  

List<?>List<Number>List<Integer>

的共同父母

因为有必要查看教程的上下文。

答案 3 :(得分:3)

以下是这些方法在Java中使用泛型的类型:

interface Collection<E> {
...
public boolean contains(Object o);
public boolean containsAll(Collection<?> c);
...
}

第一种方法根本不使用泛型!第二种方法是我们第一眼看到的 一个重要的缩写。 Collection类型代表:

Collection<? extends Object>

扩展对象是通配符最常见的用途之一,因此它是有道理的 提供一个简短的写作形式。

答案 4 :(得分:3)

您正在将OOP继承或具体类型的概念与这些泛型之间的泛型类型关系混合使用。

教程中关于Wildcards and Subtypes的一句话说明了一切:

  

为了在这些类之间创建关系...使用上限有界的通配符

generic type relationships ?只是可能的通配符? extends <type>(上边界通配符),? super <type>(下边界通配符)和实际{{}的最上限。 1}}(完全匹配或&#34;上限和下限的通配符&#34;)。

通配符用于使泛型和OOP的两个概念彼此巧妙地工作,但它们是不一样的。简单地说:typeList<?>List<Integer>的共同父项,因为通配符关系被指定为使得任何其他通配符与List<Number>创建子类型关系。 这或多或少是非正式的解释,请看dejvuth对规范的具体部分的答案。