The HIRO Says

If you smell what The HIRO is cooking!!!

generics に関する配列とリストの違い(1/3)−covariant?

Java プログラマ的には、だいたい同様のものとして扱われる配列(String[])リスト(java.util.List)
これを generics の観点からみると、これらの間にいくつかはっきりした違いが見受けられます。


以下、3回に分けて、配列とリストの違いについて記述していこうと思います。
第1回は、謎のキーワード”covariant”についてです。


covariant とは

”covariant”を英語辞典で調べると、「共変の」という意味です。
…で?(゚д゚)


プログラムで説明すると簡単かも。
「A が B の子クラスならば、A の配列も B の配列の子クラスである」という意味です。


covariant の具体例

String は、Object の子クラスです。
そのため、String の配列は、Object の配列の子クラスになります。
なので、

    Object[] objectArray = new String[3];

と定義することは可能です。


generic なリストは covariant ではない!

配列と同様に考えると、

    List list = new ArrayList();

はOKなのでは?と思いますが…
これはコンパイルエラーになります。
というのは、リストの型パラメータについては covariant ではないからです。
※Effective Java では、これを”invariant”(不変の)という用語で表しています。


但し、以下のコードはコンパイルエラーにはなりません。

    List list = new ArrayList();

なぜならば、List は、List(型定義なし)の子供に当たるからです。


invariant である意味

generic なリストが invariant なのは、実行時の型保障の問題があるからなのですが…
これは次回に説明します。(・∀・)