List <?>是List <Integer>和List <Number>的公共父项吗?
从这个Oracle教程中 ,
虽然
Integer
是Number
的子types,但List<Integer>
不是List<Number>
的子types,实际上这两个types是不相关的。
List<Number>
和List<Integer>
的公共父级是List<?>
。
我的问题是关于第二句话。 我们怎么能说List<?>
是List<Number>
和List<Integer>
的公共父项?
?
代表未知types,可以是任何参考types。 即使我这样说?
在这里是Object
, Object
是Integer
和Number
的公共父项并不意味着List<Object>
成为List<Integer>
和List<Number>
的公共父项。
您需要了解的上下文不是Integer
或Number
而是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),参数化types
C<T1,...,Tn>
的直接超types,其中Ti(1≤i≤n)是types,都是以下内容:
…
C<S1,...,Sn>
,其中Si
包含Ti
(1≤i≤n)(§4.5.1)
通过用List
replaceC
并且n=1
,我们知道List<?>
是List<Number>
和List<Integer>
的直接超typesif ?
包含Number
和Integer
。
我们可以certificate这一点?
包含 Number
和Integer
因为从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>
你只能做这个任务?
是Integer
和Number
的共同父项。 我认为在与通配符和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>
扩展对象是通配符最常用的用法之一,所以提供一个简短的表单来编写它是有意义的。