这是一小段代码,摘自Stanford Parser随附的一些示例。我从事Java开发已有大约4年的时间,但是对于这种代码应该指出什么却从未有过非常深刻的了解。
List<? extends HasWord> wordList = toke.tokenize();
我不担心代码的细节。我感到困惑的是,通用表达式应该确切地用英语传达。
谁可以给我解释一下这个?
? extends HasWord
表示“扩展的类/接口HasWord”。换句话说,HasWord它本身或其任何子代…基本上可以与instanceof HasWordplus 一起使用的任何东西null。
asWord”
HasWord
instanceof HasWordplus
用更专业的术语来说,? extends HasWord是有界通配符,在第139页的有效Java 3rd Edition的项目31中进行了介绍。有界通配符的部分是从第134页开始的第28项。
更新:由于Oracle不久前将其删除,因此PDF链接已更新。现在,它指向由伦敦玛丽皇后大学电子工程与计算机科学学院托管的副本。
更新2:让我们更详细地说明为什么要使用通配符。
如果声明一个方法的签名希望你传入List<HasWord>,那么唯一可以传入的是List<HasWord>。
List<HasWord>
但是,如果所说的签名是,List<? extends HasWord>那么你可以List<ChildOfHasWord>改为输入。
List<? extends HasWord>
List<ChildOfHasWord>
请注意,List<? extends HasWord>和之间有细微的差别List<? super HasWord>。正如Joshua Bloch所说:PECS =生产者扩展,消费者超级。
List<? super HasWord>
Joshua Bloch
PECS =
这意味着,如果传入的是你的方法从中提取数据的集合(即,该集合正在生成供你的方法使用的元素),则应使用extends。如果你传入的是方法要向其中添加数据的集合(即该集合正在消耗你的方法创建的元素),则应使用super。
这听起来可能令人困惑。但是,你可以在List的sort命令中看到它(这只是Collections.sort的两个参数版本的快捷方式)。而不是取一个Comparator<T>,实际上需要一个Comparator<? super T>。在这种情况下,比较器将使用的元素,List以便对列表本身进行重新排序。
List
sort
Collections.sort
Comparator<T>
Comparator<? super T>