Java泛型类型参数中的问号是什么意思?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3009745/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What does the question mark in Java generics' type parameter mean?
提问by sholsapp
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.
这是从斯坦福解析器附带的一些示例中提取的一小段代码。我已经用 Java 开发了大约 4 年,但从来没有对这种风格的代码应该表示什么有非常深刻的理解。
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?
谁可以给我解释一下这个?
采纳答案by Powerlord
? extends HasWord
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
.
表示“扩展HasWord
. 的类/接口”。换句话说,HasWord
它本身或它的任何孩子......基本上任何可以与instanceof HasWord
plus一起使用的东西null
。
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.
在更专业的术语中,? extends HasWord
是一个有界通配符,在Effective Java 3rd Edition 的Item 31 中涵盖,从第 139 页开始。第二版中的同一章可在线获取为 PDF;关于有界通配符的部分是从第 134 页开始的第 28 项。
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.
更新:PDF 链接已更新,因为 Oracle 不久前将其删除。它现在指向由伦敦玛丽女王大学电子工程和计算机科学学院主办的副本。
Update 2: Lets go into a bit more detail as to why you'd want to use wildcards.
更新 2:让我们更详细地了解为什么要使用通配符。
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<HasWord>
,那么您唯一可以传入的是List<HasWord>
。
However, if said signature was List<? extends HasWord>
then you could pass in a List<ChildOfHasWord>
instead.
但是,如果上述签名是,List<? extends HasWord>
则您可以传入 aList<ChildOfHasWord>
代替。
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.
请注意,List<? extends HasWord>
和之间存在细微差别List<? super HasWord>
。正如 Joshua Bloch 所说:PECS = 生产者扩展,消费者超级。
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
.
这意味着,如果您传入一个您的方法从中提取数据的集合(即该集合正在为您的方法生成元素),您应该使用extends
. 如果您传入一个您的方法向其添加数据的集合(即该集合正在使用您的方法创建的元素),则它应该使用super
.
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.
这听起来可能令人困惑。但是,您可以在List
'ssort
命令中看到它(这只是 Collections.sort 的双参数版本的快捷方式)。Comparator<T>
它实际上需要一个,而不是一个Comparator<? super T>
。在这种情况下,Comparator 正在消耗 的元素,List
以便对 List 本身重新排序。
回答by Jherico
A question mark is a signifier for 'any type'. ?
alone means
问号是“任何类型”的标志。 ?
单独意味着
Any type extending
Object
(includingObject
)
任何类型的扩展
Object
(包括Object
)
while your example above means
而你上面的例子意味着
Any type extending or implementing
HasWord
(includingHasWord
ifHasWord
is a non-abstract class)
任何扩展或实现的类型
HasWord
(包括HasWord
ifHasWord
是非抽象类)
回答by jjnguy
In English:
用英语:
It's a
List
of some type that extends the classHasWord
, includingHasWord
它
List
是扩展类的某种类型HasWord
,包括HasWord
In general the ?
in generics means any class. And the extends SomeClass
specifies that that object must extend SomeClass
(or be that class).
一般来说?
,泛型意味着任何类。并且extends SomeClass
指定该对象必须扩展SomeClass
(或成为该类)。
回答by limc
List<? extends HasWord>
accepts any concrete classes that extends HasWord. If you have the following classes...
List<? extends HasWord>
接受任何扩展 HasWord 的具体类。如果您有以下课程...
public class A extends HasWord { .. }
public class B extends HasWord { .. }
public class C { .. }
public class D extends SomeOtherWord { .. }
... the wordList
can ONLY contain a list of either As or Bs or mixture of both because both classes extend the same parent or null
(which fails instanceof checks for HasWorld
).
...wordList
只能包含 As 或 Bs 或两者混合的列表,因为这两个类都扩展了相同的父类或null
(实例化检查失败HasWorld
)。
回答by Tom Hawtin - tackline
Perhaps a contrived "real world" example would help.
也许一个人为的“真实世界”的例子会有所帮助。
At my place of work we have rubbish bins that come in different flavours. All bins contain rubbish, but some bins are specialist and do not take all types of rubbish. So we have Bin<CupRubbish>
and Bin<RecylcableRubbish>
. The type system needs to make sure I can't put my HalfEatenSandwichRubbish
into either of these types, but it can go into a general rubbish bin Bin<Rubbish>
. If I wanted to talk about a Bin
of Rubbish
which may be specialised so I can't put in incompatible rubbish, then that would be Bin<? extends Rubbish>
.
在我工作的地方,我们有不同口味的垃圾桶。所有垃圾桶都装有垃圾,但有些垃圾桶是专门的垃圾桶,不会收集所有类型的垃圾。所以我们有Bin<CupRubbish>
和Bin<RecylcableRubbish>
。类型系统需要确保我不能把我的HalfEatenSandwichRubbish
放入这两种类型中的任何一种,但它可以进入一个普通的垃圾箱Bin<Rubbish>
。如果我想谈Bin
的Rubbish
可以专业,所以我不能把不兼容的垃圾,那么这将是Bin<? extends Rubbish>
。
(Note: ? extends
does not mean read-only. For instance, I can with proper precautions take out a piece of rubbish from a bin of unknown speciality and later put it back in a different place.)
(注意:? extends
并不意味着只读。例如,我可以采取适当的预防措施从未知专业的垃圾箱中取出一块垃圾,然后将其放回其他地方。)
Not sure how much that helps. Pointer-to-pointer in presence of polymorphism isn't entirely obvious.
不知道这有多大帮助。存在多态的指针到指针并不完全明显。
回答by leo9r
The question mark is used to define wildcards. Checkout the Oracle documentation about them: http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html
问号用于定义通配符。查看有关它们的 Oracle 文档:http: //docs.oracle.com/javase/tutorial/java/generics/wildcards.html