LoginSignup
12
18

More than 5 years have passed since last update.

<? extends T>と<? super T>の使い方

Last updated at Posted at 2016-08-20

具体的な型

class
class Animal(){
}
class Dog extends Animal(){
}

DogはAnimalのサブクラスとします
new ArrayList<? extends Animal>とか
new ArrayList<? super Dog>などのワイルドカードオブジェクトを生成できません
ワイルドカード型はメソッドのパラメータ型に使います

List<Animal>とList<Dog>の関係

不変性
List<Animal>a=new ArrayList<>();
List<Dog>d=new ArrayList<>();
//===========================代入
a=d;//コンパイルエラー
d=a;//コンパイルエラー
//===========================メソッド呼び出し
//定義側
void func(List<Animal> p){
... pをList<Animal>として操作
}
//呼び出し側
func(animal);//有効
func(dog);//コンパイルエラー

オブジェクト代入は相互に不可能
メソッド呼び出しは、同じ型のみ可能
結論
Dog extends Animal だったとしてもList<Dog>とList<Array>に関係性はありません

List<? extends Animal>とList<Dog>の関係

共変性
List<Dog>d=new ArrayList<>();
//===========================代入
List<? extends Animal>ea;
ea=d;//有効
d=ea;//コンパイルエラー
//===========================メソッド呼び出し
//定義側
void func(List<?extends Animal> p){
... pをList<Animal>として操作
}
//呼び出し側
func(dog);//有効
func(animal);//有効

List<Dog>型はList<?extends Animal>に代入可能
List<Dog>型はfunc(List<?extends Animal>)のパラメータにできます
結論
List<Dog>型はList<?extends Animal>にアップキャスト可能
Dog extends Animal =>(ならば) List<Dog> extends List<? extends Array>と扱えます
上記 =>の両辺でDogとAnimalの位置関係が同じなので共変関係

List<? super Dog>とList<Animal>の関係

反変性
List<Animal>a=new ArrayList<>();
//===========================代入
List<? super Dog>sd;
sd=a;//有効
a=sd;//コンパイルエラー
//===========================メソッド呼び出し
//定義側
void func(List<? super Dog> p){
... funcはp.addするためのもの pはObject型として扱う
}
//呼び出し側
func(animal);//有効

List<Animal>型はList<?super Dog>に代入可能
List<Animal>型はfunc(List<?super Dog>)のパラメータにできます
結論
List<Animal>型はList<?super Dog>にアップキャスト可能
Dog extends Animal =>(ならば) List<Animal> extends List<? super Dog>と扱えます
上記 =>の両辺でDogとAnimalの位置関係が逆転しているため反変関係

12
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
18