型パラメータには、<? super E>という書き方もあります。
今回は、この super について説明します。
例
前回使用した Stack クラスに、popAll() メソッドを定義するとします。
popAll() メソッドは、Stack の要素を全て、引数の Collection に add するという内容とします。
(引数にデータを移すことがポイント)
public void popAll(Collectiondst) { while (!this.isEmpty()) { dst.add(this.pop()); } }
問題点
前回と同じで、型パラメータが一致しないとコンパイルエラーになります。
Stacktarget = new Stack (); target.popAll(new ArrayList ());
【エラーメッセージ】
popAll(Collection
解決策
前回は、引数の値を Stack 内で使用しました。
今回は、Stack の値を引数にセットします。
つまり、データの流れが前回と逆になります。
このような場合は、super を使います。
public void popAll(Collection<? super E> dst) {
指針
今回の popAll のように、型パラメータがクラス定義と一致しない場合かつ、プログラム内の値を引数にセットする処理を行う場合、super と定義するとうまく行きます。
面倒くさいですね。
PECS
Effective Java(原著)によると、この extends と super のルールは、”PECS”として覚えると良いそうです。
PECS:「Producer-Extends, Consumer-Super」の略
- producer:引数がプログラム内で使用されるものの場合(引数から内部データを「生成する」という意味か)
- consumer:引数がプログラムからセットされるものの場合(引数が内部データを「消費する」という意味か)