问题描述
我使用泛型相当长的时间,但我从来没有使用像建设名单,LT ;?超级T>
。
这是什么意思?如何使用它?它是如何擦除之后看?
我也想知道:这是在泛型编程(模板编程吗?),或者它只是一个java发明什么标准?请问C#,例如,允许类似的结构?
当你想消费从集合项到另一个这个结构用采集。例如。你有一个通用的的Stack
,你想添加一个 popAll
方法,它接受一个集合作为参数,并弹出所有项目从堆栈进去。按常理,这个代码应该是合法的:
堆栈<数字与GT; numberStack =新的堆栈<数字与GT;();
收集和LT;对象>对象= ...;
numberStack.popAll(对象);
但只编译如果您定义 popAll
像这样的:
//通配符类型的参数,作为一个E消费
公共无效popAll(收集和LT ;?超级E> DST){
同时)
dst.add(pop()方法)(的isEmpty(!);
}
在硬币的另一面是, pushAll
应该这样定义:
//通配符类型参数用作一个E制片
公共无效pushAll(可迭代< ;?扩展E> SRC){
为(E E:SRC)
推(E);
}
更新:乔希布洛赫传播这种记忆帮助你还记得要使用的通配符类型:
佩奇表示的生产者延伸,消费超的。 p>
有关详细信息,请参见。
I'm using generics rather long time but I've never used construction like List<? super T>
.
What does it mean? How to use it? How does it look after erasure?
I also wonder: is it something standard in generic programming (template programming?) or it's just a java 'invention'? Does c#, for example, allow similar constructions?
This construct is used when you want to consume items from a collection into another collection. E.g. you have a generic Stack
and you want to add a popAll
method which takes a Collection as parameter, and pops all items from the stack into it. By common sense, this code should be legal:
Stack<Number> numberStack = new Stack<Number>();
Collection<Object> objects = ... ;
numberStack.popAll(objects);
but it compiles only if you define popAll
like this:
// Wildcard type for parameter that serves as an E consumer
public void popAll(Collection<? super E> dst) {
while (!isEmpty())
dst.add(pop());
}
The other side of the coin is that pushAll
should be defined like this:
// Wildcard type for parameter that serves as an E producer
public void pushAll(Iterable<? extends E> src) {
for (E e : src)
push(e);
}
Update: Josh Bloch propagates this mnemonic to help you remember which wildcard type to use:
PECS stands for producer-extends, consumer-super.
For more details, see Effective Java 2nd Ed., Item 28.
这篇关于有人能解释什么呢< ;?超级T>意思是当它应该被使用,这种结构应该如何以<合作; T>和<?扩展T> ;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!