这意味着如果你传入一个集合,你的方法从中提取数据(即集合正在为你的方法生成元素),你应该使用 extends . 如果您传入的方法是您的方法添加数据(即集合正在消耗您的方法创建的元素),则应使用 super .
这可能听起来令人困惑 . 但是,您可以在 List 的sort命令中看到它(这只是Collections.sort的两个arg版本的快捷方式) . 它实际上需要 Comparator<? super T> 而不是 Comparator<T> . 在这种情况下,比较器正在使用 List 的元素,以便重新排序List本身 .
9
也许一个人为的“现实世界”的例子会有所帮助 .
在工作中,我们有不同口味的垃圾箱 . 所有垃圾箱都含有垃圾,但有些垃圾箱是专家,不会带走所有类型的垃圾 . 所以我们有 Bin<CupRubbish> 和 Bin<RecylcableRubbsih> . 类型系统需要确保我不能将 HalfEatenSandwichRubbish 放入这些类型中的任何一种,但它可以进入一个普通的垃圾箱``Bin . If I wanted to talk about a Bin of Rubbish which may be a specialist so I can't put in incompatible rubbish, then that would be Bin` .
6 回答
List<? extends HasWord>
接受任何扩展HasWord的具体类 . 如果您有以下课程.........
wordList
只能包含As或Bs的列表或两者的混合,因为这两个类都扩展了相同的父级或null
(无法检查HasWorld
的instanceof) .问号是'any type'的能指 .
?
独自意味着而你上面的例子意味着
问号用于定义通配符 . 查看有关它们的Oracle文档:http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html
表示“扩展
HasWord
的类/接口” . 换句话说,HasWord
本身或其任何一个孩子......基本上任何与instanceof HasWord
加null
一起使用的东西 .在更多技术术语中,
? extends HasWord
是有界通配符,涵盖在Effective Java 3rd Edition的第31项中,从第139页开始 . 第2版的同一章是available online as a PDF;有界通配符上的部分是从第134页开始的第28项 .更新:PDF链接已更新,因为Oracle在一段时间后删除了它 . 它现在指向由伦敦玛丽女王大学电子工程和计算机科学学院主办的副本 .
更新2:让我们详细了解您为什么要使用通配符 .
如果您声明一个其签名希望您传入
List<HasWord>
的方法,那么您唯一可以传入的是List<HasWord>
.但是,如果所述签名是
List<? extends HasWord>
,则可以传入List<ChildOfHasWord>
.请注意
List<? extends HasWord>
和List<? super HasWord>
之间存在细微差别 . 正如Joshua Bloch所说:PECS = 生产环境 者延伸,消费者超级 .这意味着如果你传入一个集合,你的方法从中提取数据(即集合正在为你的方法生成元素),你应该使用
extends
. 如果您传入的方法是您的方法添加数据(即集合正在消耗您的方法创建的元素),则应使用super
.这可能听起来令人困惑 . 但是,您可以在
List
的sort命令中看到它(这只是Collections.sort的两个arg版本的快捷方式) . 它实际上需要Comparator<? super T>
而不是Comparator<T>
. 在这种情况下,比较器正在使用List
的元素,以便重新排序List本身 .也许一个人为的“现实世界”的例子会有所帮助 .
在工作中,我们有不同口味的垃圾箱 . 所有垃圾箱都含有垃圾,但有些垃圾箱是专家,不会带走所有类型的垃圾 . 所以我们有
Bin<CupRubbish>
和Bin<RecylcableRubbsih>
. 类型系统需要确保我不能将HalfEatenSandwichRubbish
放入这些类型中的任何一种,但它可以进入一个普通的垃圾箱``Bin. If I wanted to talk about a
Binof
Rubbishwhich may be a specialist so I can't put in incompatible rubbish, then that would be
Bin` .(注意:
? extends
并不意味着只读 . 例如,我可以采取适当的预防措施从一个未知专业的垃圾箱中取出一块垃圾,然后将其放回另一个地方 . )不知道有多大帮助 . 存在多态性的指针指针并不完全明显 .
用英语讲:
通常,泛型中的
?
表示任何类 . 并且extends SomeClass
指定该对象必须扩展SomeClass
(或者是该类) .