マイナー・マイナー

隠れた名作の発掘が生きがい。

ジェネリックスにワイルドカードを用いた後の注意事項


スポンサードリンク

ジェネリックスにはワイルドカード「?」を用いることができます.これを用いることで,型パラメータにスーパークラスやサブクラスを指定することができますが,その後の使用に制限が付きます.


ワイルドカードを用いた次の記述を考えます.型パラメータにクラス名のスーパクラスを指定できる記述が(1),サブクラスを指定できる記述が(2)にあたります.

(1) <? super Sub>
(2) <? extends Super>


コレクションの型パラメータを(1)のように記述した場合,オブジェクトにはSubしか追加できません.これは,コレクションの型パラメータをSubで指定した場合,コレクションにはSubのスーパークラスを追加することができなくなるためです.


コレクションの型パラメータを(2)のように記述した場合,オブジェクトは追加することができません.これは,コレクションの型パラメータをSuperのサブクラスで指定すると,SuperはSuperのサブクラスに追加することができなくなるためです.


次に確認例を示します.list1,list2は型パラメータをそれぞれSub型,Super型にしましたが,(1)はSub型になる可能性があるため,Superオブジェクトは入れることができません.list3,list4は型パラメータをそれぞれSub型,Super型にしましたが,(2)はSub型になったらSuper型は入れることができなくなるため,どんなオブジェクトも入れることができません.

import java.util.ArrayList;
import java.util.List;

class Super {}

class Sub extends Super {}

public class BoundedWildcardsTest {

	public static void main(String[] args) {

		List<? super Sub> list1 = new ArrayList<Sub>();
		list1.add(new Sub());
		//list1.add(new Super());	//コンパイルエラー
		List<? super Sub> list2 = new ArrayList<Super>();
		list2.add(new Sub());
		//list2.add(new Super());	//コンパイルエラー
		List<? extends Super> list3 = new ArrayList<Super>();
		//list3.add(new Super());	//コンパイルエラー
		//list3.add(new Sub());		//コンパイルエラー
		List<? extends Super> list4 = new ArrayList<Sub>();
		//list4.add(new Super());	//コンパイルエラー
		//list4.add(new Sub());		//コンパイルエラー
	}
}