それよりも複雑です。ジェネリックはバイトコードで消去され、の消去はT[]
ですObject[]
。同様に、の戻り値はにget()
なりObject
ます。型システムの整合性を維持するために、クラスが実際に使用されるときにチェックされたキャストが挿入されます。
Integer i = list.get(0);
に消去されます
Integer i = (Integer) list.get(0);
その場合、ArrayList内の型チェックは冗長です。ただし、とは両方ともチェックされていないキャストであり、実行時のオーバーヘッドが発生しないため、これは実際には重要で(T)
は(T[])
ありません。
次のようなチェック済みのArrayListを作成できます。
T[] array = Array.newInstance(tClass, n);
これにより、ヒープの汚染を防ぐことができますが、タイプチェックが冗長になります(コードの呼び出しで合成キャストを抑制することはできません)。また、呼び出し元がArrayListに要素型のクラスオブジェクトを提供する必要があります。これにより、APIが乱雑になり、ジェネリックコードでの使用が困難になります。
編集:なぜジェネリックアレイの作成が禁止されているのですか?
1つの問題は、ジェネリックがチェックされていないのに、配列がチェックされていることです。あれは:
Object[] array = new String[1];
array[0] = 1; // throws ArrayStoreException
ArrayList list = new ArrayList<String>();
list.add(1); // causes heap pollution
したがって、配列のコンポーネントタイプが重要になります。これが、Java言語の設計者が、使用するコンポーネントタイプについて明示的に要求する理由だと思います。