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規則によれば、上記の宣言は誤りです。しかし、私はStack
ofを持ち、Integer
これに渡したいStack
a Number
。なぜそれをしないのですか?
キーワード
を常に使用する必要があるのはなぜですか? extends
使い方super
が間違っているのはなぜですか?
もちろん、消費者の視点も同じです。なぜ消費者は常にあるべきなのsuper
ですか?
PS: より具体的に言うと、上記の例は、参照されている本のセクション「項目 28」にあります。