根据 Joshua Bloch 的“Effective Java”一书,有一条关于如何/何时在泛型中使用有界通配符的规则。这条规则就是 PECS(Producer-Extends,Comsumer-Super)。当我研究以下示例时:
Stack<Number> numberStack = new Stack<Number>();
Iterable<Integer> integers = ... ;
numberStack.pushAll(integers);
我知道这条规则非常适合这个例子。我必须将该方法声明pushAll
为以下示例:
// Wildcard type for parameter that serves as an E producer
public void pushAll(Iterable<? extends E> src) {
for (E e : src)
{
push(e);
}
}
但是,如果我有以下示例,会发生什么?
Stack<Integer> integerStack = new Stack<Integer>();
Iterable<Number> numbers = ... ;
integerStack.pushAll(numbers);
我必须声明pushAll
如下:
public void pushAll(Iterable<? super E> src) {
for (E e : src)
{
push(e);
}
}
根据PECS规则,上述声明是错误的。但我想要 a Stack
of Integer
s 并传递给这个Stack
a Number
。为什么不去做呢?
为什么我应该总是使用extends
关键字?为什么使用super
是错误的?
当然,同样代表消费者的观点。为什么消费者应该永远是super
?
PS:更具体地说,您可以在参考书的“第 28 项”部分找到上述示例。