The HIRO Says

If you smell what The HIRO is cooking!!!

generics に関する配列とリストの違い(3/3)−generic な配列の禁止

前回、generic なリストは実行時に型チェックできないと説明しました。
ただ、正直これだけだと、「内部的にはそうかもしれないけれど、プログラムを組むだけならば関係ないや」という気になりがちだと思います。

ですが、これが具体的にプログラマに影響を与えるケースがあります。
その1つとして、generic な配列を作成できないことがあげられます。


どういうこと?

以下のコードは、いずれもコンパイルエラーになります。

    new List
    new List
    new E[]

generic なリストの配列、および型パラメータの配列は、作成することができません。


なぜ?

例えば、以下のように String のリストの配列が作成可能だった場合、どうなるでしょうか?

    // 仮にこれが可能だとすると…
    List strArray = new ArrayList[1];
    List  intArray = Arrays.asList(2);
    strArray[0].add("first");

    // Object は List の親クラスなので、Object に List をセットすることが可能。
    Object objects = strArray;
    // Object は Integer の親クラスでもあるので、これは文法上可能。
    // だがこれだと、List が List に置換されてしまう!
    objects[0] = intArray;

    // 実行時に、Integer が返される!→ClassCastException
    String str = strArray[0].get(0);

「generic なリストは実行時に型チェックできない」ために、最後の行は Integer を返すことを防ぐことができません。
このように、generic な配列を許容してしまうと、型の安全性が損なわれてしまうことがあり得ます。
これを防ぐために、Javaコンパイラは、generic な配列の作成を禁じています。


補足

「generic なリストは実行時に型チェックできない」ことの影響は、他にもあるかもしれません。
ですが、現時点での私の知識・調査範囲では、はっきり言えるのはこれだけでした。