Javagenerics的types参数中的问号是什么意思?
这是从斯坦福分析器附带的一些例子中抽取的一小段代码。 我已经用Java开发了大约4年,但是从来没有对这种代码风格应该表明什么有很深刻的理解。
List<? extends HasWord> wordList = toke.tokenize();
我并不担心代码的细节。 我感到困惑的是,这个genericsexpression应该用英语来expression。
谁可以给我解释一下这个?
? extends HasWord
意思是“扩展HasWord
类/接口”。 换句话说, HasWord
本身或它的任何子…基本上任何可以用instanceof HasWord
加null
。
更技术性地说, ? extends HasWord
? extends HasWord
是一个有界的通配符,在第134页开始的Effective Java第2版的第28项中有介绍。这是作为PDF在线提供的generics一章的一部分。
更新:由于Oracle删除了一段时间,PDF链接已经更新。 现在指向伦敦玛丽皇后大学电子工程与计算机科学学院的副本。
更新2:让我们进一步了解一下你为什么要使用通配符。
如果你声明一个方法的签名期望你在List<HasWord>
传递,那么你唯一可以传递的就是一个List<HasWord>
。
但是,如果签名是List<? extends HasWord>
List<? extends HasWord>
然后你可以传递一个List<ChildOfHasWord>
来代替。
请注意List<? extends HasWord>
之间有一个微妙的区别 List<? extends HasWord>
和List<? super HasWord>
List<? super HasWord>
。 正如Joshua Bloch所说:PECS =生产者延伸,超级消费者。
这意味着如果你传入一个你的方法从中获取数据的集合(即集合正在生成要使用的方法的元素),则应该使用extends
。 如果你传入一个你的方法添加数据的集合(即集合正在消耗你的方法创build的元素),它应该使用super
。
这可能听起来很混乱。 但是,您可以在List
的sort
命令中看到它(这只是Collections.sort的两个版本的快捷方式)。 而不是采取一个Comparator<T>
,它实际上需要一个Comparator<? super T>
Comparator<? super T>
。 在这种情况下,比较器消耗List
中的元素,以重新sorting列表本身。
问号是“任何types”的指示符。 ?
单独的手段
任何types的扩展
Object
(包括Object
)
而上面的例子意味着
任何扩展或实现
HasWord
types(包括HasWord
如果HasWord
是非抽象类)
List<? extends HasWord>
List<? extends HasWord>
接受任何扩展HasWord的具体类。 如果你有以下课程…
public class A extends HasWord { .. } public class B extends HasWord { .. } public class C { .. } public class D extends SomeOtherWord { .. }
… wordList
只能包含As或Bs或两者混合的列表,因为这两个类扩展了相同的父HasWorld
或null
(它没有检查HasWorld
)。
也许一个人为的“现实世界”的例子会有所帮助。
在工作中,我们有不同口味的垃圾桶。 所有垃圾箱都装有垃圾,但有些垃圾箱是专门的垃圾箱,不要带任何垃圾。 所以我们有Bin<CupRubbish>
和Bin<RecylcableRubbsih>
。 types系统需要确保我不能将我的HalfEatenSandwichRubbish
放入这两种types的任何一种,但是它可以进入一个普通的垃圾桶“Bin” . If I wanted to talk about a
. If I wanted to talk about a
垃圾桶which may be a specialist so I can't put in incompatible rubbish, then that would be
斌。
(注意: ? extends
并不意味着只读,例如我可以采取适当的预防措施从一个未知专业的垃圾箱中取出一块垃圾,然后把它放回另一个地方。)
不知道有多大的帮助。 存在多态性的指针指针并不是完全明显的。
用英语:
它是扩展
HasWord
类的一些types的List
,包括HasWord
一般来说?
在generics中是指任何类。 而extends SomeClass
的extends SomeClass
指定该对象必须扩展SomeClass
(或者是该类)。
问号用于定义通配符 。 查看关于他们的Oracle文档: http : //docs.oracle.com/javase/tutorial/java/generics/wildcards.html