これは、具体的なパラメーター化された型の配列を作成することはタイプ セーフではないためであり、それがまったく許可されていない理由です。
次のようなコードを作成しようとすると、コンパイラ エラーが発生します。
List<String>[] arr = new ArrayList<String>[10]; // Compiler error: Generic Array creation
問題は、ジェネリック型が具体化できないことです。それらの型情報は実行時に利用できません。一方、配列は、実行時に利用可能な型情報を使用しArrayStoreCheck
て、配列に挿入された要素が配列の型と互換性があるかどうかを確認します。したがって、配列とジェネリックを混同すると、実行時に驚くべき動作が発生する可能性があります。
たとえば、次のコードを考えてみましょう。
List<String>[] arr = new ArrayList<String>[10]; // Suppose this was valid
Object[] objArr = arr; // This is valid assignment. A `List[]` is an `Object[]`
objArr[0] = new ArrayList<Integer>(); // There you go. A disaster waiting at runtime.
String str = arr[0].get(0); // Assigned an `Integer` to a `String`. ClassCastException
そのため、最初の代入がコンパイルされていれば、コンパイラには問題ないように見える 4 番目の代入がClassCastException
実行時にスローされます。
ただし、どちらも完全に具体化可能な型であるため、生の型の配列 - ArrayList
、または無制限のワイルドカード パラメータ化された型 -を作成できます。ArrayList<?>
したがって、次の配列の作成は有効です。
List[] arr = new ArrayList[10];
List<?>[] arr2 = new ArrayList<?>[10];
生の型または無制限のワイルドカード型に関連付けられた型情報がないため、実行時に失うものは何もありません。したがって、これらの型は具体化可能であり、配列の適切なコンポーネント型です。そのため、Entry[]
の代わりに が使用されEntry<K, V>[]
ます。
以下も参照してください。