什么是
下面是一个简单的Stack的API接口:
public class Stack{
public Stack();
public void push(E e):
public E pop();
public boolean isEmpty();
}
假设想增加一个方法,按顺序将一系列元素全部放入Stack中,你可能想到的实现方式如下:
public void pushAll(Iterable src){
for(E e : src)
push(e)
}
假设有个Stack,想要灵活的处理Integer,Long等Number的子类型的集合
Stack numberStack = new Stack();
Iterable integers = ....;
numberStack.pushAll(integers);
此时
幸好java提供了一种叫有限通配符的参数化类型,pushAll参数替换为“E的某个子类型的Iterable接口”:
public void pushAll(Iterable extends E> src){
for (E e: src)
push(e);
}
这样就可以正确编译了,这里的 extends E>就是所谓的 producer-extends。这里的Iterable就是生产者,要使用 extends E>。因为Iterable extends E>可以容纳任何E的子类。在执行操作时,可迭代对象的每个元素都可以当作是E来操作。
与之对应的是:假设有一个方法popAll()方法,从Stack集合中弹出每个元素,添加到指定集合中去。
public void popAll(Collection dst){
if(!isEmpty())
dst.add(pop());
}
假设有一个Stack和Collection对象:
Stack numberStack = new Stack();
Collection objects = ...;
numberStack.popAll(objects);
同样上面这段
总结:
1、如果你是想遍历collection,并对每一项元素操作时,此时这个集合时生产者(生产元素),应该使用 Collection extends Thing>
2、如果你是想添加元素到collection中去,那么此时集合时消费者(消费元素)应该使用Collection super Thing>