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)
通过用ListreplaceC并且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 SS.- …
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>
扩展对象是通配符最常用的用法之一,所以提供一个简短的表单来编写它是有意义的。