50
53

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

<? extends ...>や<? super ...>って何?代入編

Last updated at Posted at 2014-11-15

はじめに

<? extends E>や<? super E>が使われているクラスにどのような値が代入できるのか考えよう。
手っ取り早く結論を知りたい人は図解を見てください。

準備

2つのクラスA,Bがある。クラスBはクラスAのサブクラスであるとする:

class A {}
class B extends A {}

<? extends E>

<? extends E> はE型のすべてのサブクラスを表している。だから、<? extends A>が表すクラスは<? extends B>が表すクラスをすべて含んでいることがわかる。この性質があるので、以下の代入関係が成り立つ:

List<? extends A> listA;
List<? extends B> listB;

listA = listB; //OK
listB = listA; //コンパイルエラー

<? extends B>はクラスAを含んでいないので、listBにlistAを代入することはできない。代入できてしまうとキャストが必要になり、型安全でなくなってしまう。

また、<? extends E>はE型自身を含むので、以下の代入関係も成り立つ:

List<? extends A> list1;
List<A> list2;

list1 = list2; //OK
list2 = list1; //コンパイルエラー

<? super E>

<? super E> はE型のすべてのスーパークラスを表している。だから、<? super E>が表すクラスは<? super A>が表すクラスをすべて含んでいることがわかる。この性質があるので、以下の代入関係が成り立つ:

List<? super A> listA;
List<? super B> listB;

listA = listB; //コンパイルエラー
listB = listA; //OK

<? extends E>の場合と比較すると、継承関係と代入関係が逆になっていることに注意しよう。

また、<? super E>はE型自身を含むので、以下の代入関係も成り立つ:

List<? super A> list1;
List<A> list2;

list1 = list2; //OK
list2 = list1; //コンパイルエラー

<?>

<?> はすべてのクラスを表している。つまり、<? extends E>や <? super E>なども含めて、すべてのクラスを代入することができる。

List<?> list1;
List<? extends A> list2 = null;
List<? super A> list3 = null;
List<A> list4 = null;

list1 = list2; //OK
list1 = list3; //OK
list1 = list4; //OK

<? extends Object>

<? extends Object>は、Objectのサブクラスを表しているので、<?>と同じくすべてのクラスを表している。よって、<? extends E>とは異なり、<? super E>を代入することができる。

List<? extends Object> list1;
List<? extends A> list2 = null;
List<? super A> list3 = null;
List<A> list4 = null;
List<?> list5 = null;

list1 = list2; //OK
list1 = list3; //OK
list1 = list4; //OK
list1 = list5; //OK

図解

ここまでの代入関係を図にしてみると、以下のようになる。
矢印は、矢印の元が矢印の先に代入できることを表す。
直接1本の矢印でつながっていなくても、複数の矢印でつながっていれば代入できる。

ジェネリクスの継承関係.png

参考

Java Language Specification 4.5.1. Type Arguments of Parameterized Types
https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.5.1

50
53
1

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
50
53

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?