Java泛型类型参数中的问号是什么意思? [英] What does the question mark in Java generics' type parameter mean?

查看:123
本文介绍了Java泛型类型参数中的问号是什么意思?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

This is a small snippet of code taken from some of the examples that accompany the Stanford Parser. I've been developing in Java for about 4 years, but have never had a very strong understanding of what this style of code is supposed to indicate.

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

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

I'm not worried about the details of the code. What I'm confused about is what exactly the generic expression is supposed to convey, in English.

有人可以向我解释一下吗?

Can someone explain this to me?

推荐答案

? extends HasWord

表示扩展 HasWord 的类/接口."换句话说,HasWord 本身或它的任何子项...基本上任何可以与 instanceof HasWordnull 一起使用的东西.

means "A class/interface that extends HasWord." In other words, HasWord itself or any of its children... basically anything that would work with instanceof HasWord plus null.

用更专业的术语来说,?extends HasWord 是一个有界通配符,包含在 Effective Java 3rd Edition,从第 139 页开始.与第 2 版相同的章节是 以 PDF 格式在线提供;有界通配符的部分是从第 134 页开始的第 28 项.

In more technical terms, ? extends HasWord is a bounded wildcard, covered in Item 31 of Effective Java 3rd Edition, starting on page 139. The same chapter from the 2nd Edition is available online as a PDF; the part on bounded wildcards is Item 28 starting on page 134.

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

Update: PDF link was updated since Oracle removed it a while back. It now points to the copy hosted by the Queen Mary University of London's School of Electronic Engineering and Computer Science.

更新 2:让我们更详细地了解为什么要使用通配符.

Update 2: Lets go into a bit more detail as to why you'd want to use wildcards.

如果您声明一个方法,其签名希望您传入 List,那么您唯一可以传入的是 List.

If you declare a method whose signature expect you to pass in List<HasWord>, then the only thing you can pass in is a List<HasWord>.

但是,如果所述签名是 List 那么你可以传入一个 List 代替.

However, if said signature was List<? extends HasWord> then you could pass in a List<ChildOfHasWord> instead.

注意ListList.正如 Joshua Bloch 所说:PECS = 生产者扩展,消费者超级.

Note that there is a subtle difference between List<? extends HasWord> and List<? super HasWord>. As Joshua Bloch put it: PECS = producer-extends, consumer-super.

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

What this means is that if you are passing in a collection that your method pulls data out from (i.e. the collection is producing elements for your method to use), you should use extends. If you're passing in a collection that your method adds data to (i.e. the collection is consuming elements your method creates), it should use super.

这听起来可能令人困惑.但是,您可以在 Listsort 命令(这只是 Collections.sort 的两个参数版本的快捷方式).它实际上没有使用 Comparator,而是使用 Comparator.在这种情况下,比较器正在消耗 List 的元素,以便对 List 本身重新排序.

This may sound confusing. However, you can see it in List's sort command (which is just a shortcut to the two-arg version of Collections.sort). Instead of taking a Comparator<T>, it actually takes a Comparator<? super T>. In this case, the Comparator is consuming the elements of the List in order to reorder the List itself.

这篇关于Java泛型类型参数中的问号是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆