List <?>是List <Integer>和List <Number>的公共父项吗?

从这个Oracle教程中 ,

虽然IntegerNumber的子types,但List<Integer>不是List<Number>的子types,实际上这两个types是不相关的。

List<Number>List<Integer>的公共父级是List<?>

我的问题是关于第二句话。 我们怎么能说List<?>List<Number>List<Integer>的公共父项?

? 代表未知types,可以是任何参考types。 即使我这样说? 在这里是ObjectObjectIntegerNumber的公共父项并不意味着List<Object>成为List<Integer>List<Number>的公共父项。

您需要了解的上下文不是IntegerNumber而是List 。 假设您是创buildList类的人,那么您将如何创build该类,以便仅支持特定types的类。

是的,那个List类不会使用Object作为它的types,而是使用通配符?

当WildCards的文件说

那么什么是所有types的超types? 它写成Collection<?> (发音为“未知集合”)

列表也是一样的。

那么什么是所有types的超types? 它写成List<?> (发音为“未知列表”)

我们可以certificateList<?>List<Number>List<Integer>的超types。

从JLS 4.10.2 (重点是我的):

给定genericstypes声明C <F1,…,Fn>(n> 0),参数化typesC<T1,...,Tn>直接超types,其中Ti(1≤i≤n)是types,都是以下内容:

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

通过用ListreplaceC并且n=1 ,我们知道List<?>List<Number>List<Integer>的直接超typesif ? 包含NumberInteger

我们可以certificate这一点? 包含 NumberInteger因为从JLS 4.5.1 :

通配符? extends Object ? extends Object相当于无界通配符?

并进一步:

如果由T2表示的types集合可certificate是在T1的下面规则的自反和传递闭包下的一组types的一个子集,那么types实参T1被认为包含另一个types实参T2 ,写为T2 <= T1其中<:表示子types(§4.10)):

  • ? extends T ? extends T <= ? extends S 如果T <:S则? extends S S.
  • T <= ? extends T ? extends T

我们可以用上面的规则来certificateNumber <= ? ,因为Number <= ? extends Number ? extends Number <= ? extends Object ? extends Object = ?

这个教程是关于通配符的。 所以他们想要解释何时以及如何使用它们。 当你阅读前面的例子代码:

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

你只能做这个任务?IntegerNumber的共同父项。 我认为在与通配符和generics的关系中可以这样说:

List<?>List<Number>List<Integer>的公共父项

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

您将OOPinheritance或具体types的概念与这些generics之间的genericstypes关系混合在一起。

关于通配符和子types的教程中的一句话说明了这一切:

为了创build这些类之间的关系…使用上界有界的通配符

对于genericstypes的关系 ? 简直是可能的通配符中最上面的界限? extends <type> ? extends <type> (上界的通配符),? ? super <type> (下界的通配符)和实际的type (完全匹配或“上界和下界通配符”)。

通配符被用来使generics和面向对象的两个概念彼此巧妙地工作,但它们是不一样的。 简单地说: List<?>List<Integer>List<Number>的公共父项,因为通配符关系被指定为使得任何其他通配符与? 。 这或多或less是非正式的解释,请看dejvuth对规范具体部分的回答。

下面是Java中generics方法的types:

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

第一种方法根本不使用generics! 第二种方法是我们第一次看到一个重要的缩写。 types集合代表:

Collection<? extends Object>

扩展对象是通配符最常用的用法之一,所以提供一个简短的表单来编写它是有意义的。