ジェネリックスにはワイルドカード「?」を用いることができます.これを用いることで,型パラメータにスーパークラスやサブクラスを指定することができますが,その後の使用に制限が付きます.
ワイルドカードを用いた次の記述を考えます.型パラメータにクラス名のスーパクラスを指定できる記述が(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()); //コンパイルエラー } }