小编典典

Java泛型的类型参数中的问号是什么意思?

all

这是从斯坦福解析器附带的一些示例中截取的一小段代码。我已经用 Java 开发了大约 4 年,但从未对这种代码风格应该表示什么有非常深刻的理解。

List<? extends HasWord> wordList = toke.tokenize();

我不担心代码的细节。我感到困惑的是,通用表达式应该用英语表达什么。

谁可以给我解释一下这个?


阅读 66

收藏
2022-05-24

共1个答案

小编典典

? extends HasWord

表示“扩展的类/接口HasWord。” 换句话说,HasWord它自己或它的任何孩子......基本上任何可以与instanceof HasWordplus一起使用的东西null

用更专业的术语来说,是一个有界通配符,在Effective Java 3rdEdition? extendsHasWord的第 31 条中介绍,从第 139 页开始。第 2 版中的同一章节以 PDF
形式在线提供
;有界通配符部分是从第 134
页开始的第 28
项。

更新:由于 Oracle 不久前将其删除,PDF 链接已更新。它现在指向伦敦玛丽女王大学电子工程与计算机科学学院主办的副本。

更新 2:让我们更详细地说明为什么要使用通配符。

如果你声明了一个方法,其签名希望你传入List<HasWord>,那么你唯一可以传入的就是一个List<HasWord>.

但是,如果所述签名是,List<? extends HasWord>那么您可以传入 aList<ChildOfHasWord>代替。

List<? extends HasWord>请注意,和之间存在细微差别List<? super HasWord>。正如 Joshua Bloch
所说:PECS = producer-extends,consumer-super。

这意味着如果您传入一个集合,您的方法从中提取数据(即该集合正在生成供您的方法使用的元素),您应该使用extends.
如果您要传入您的方法添加数据的集合(即该集合正在使用您的方法创建的元素),它应该使用super.

这听起来可能令人困惑。但是,您可以在Listsort命令中看到它(这只是 Collections.sort
的双参数版本的快捷方式)。Comparator<T>它实际上需要一个 ,而不是一个Comparator<? super T>。在这种情况下,比较器正在消耗 的元素,List以便对 List 本身重新排序。

2022-05-24