それはです:
add(i.toArray(new Animal[i.size()]))
List.toArrayは関係なく、リスト上の型引数の、Object[]
を返します:あなたはnew List<String>().toArray()
を書く場合でも、あなたはObject[]
を取得します。ただし、version of toArray that takes an array to fillは、正しい型の配列を返します。new List<String>().toArray(new String[0])
と書くと、String[]
が得られます。渡す配列のサイズは、リストのサイズと一致する必要はありませんが、確実に行うことをお勧めします。
これは、最終的には、ジェネリックのややこしい機能のためです。一見すると、String[]
とList<String>
は基本型の意味が似ていると思うかもしれません。一つは文字列の配列、もう一つは文字列のリストです。
しかし、実際には非常に異なっています。
配列は言語プリミティブであり、その型がベーキングされています。 16進エディタを使用してJVMのメモリ内の配列インスタンスを見た場合、保持しているオブジェクトのタイプのレコードを(近くのどこかに)見つけることができます。つまり、未知のコンポーネントタイプの配列のインスタンスを取る場合は、find out what that type isとすることができます。逆に、create an instance of an arrayに行く場合は、必要なコンポーネントの種類を知る必要があります。
List
は、他の一方で、Javaで大まかに言えば、それはコンパイラに存在するものですが、実行時に(コンパイラがあなたをすることを確認することができない、ということを意味し、type erasureで実装されたジェネリックを使用していますそれは正しくなるが、JVMはできない)。これにより、シンプルで効率的な実装が可能になります(JVMを変更せずにジェネリック以前のJavaに追加するだけのシンプルな実装です)が、いくつかの欠点があります。特に、実行時に型引数タイプ引数はコンパイラにのみ存在するため、ジェネリッククラスの特定のインスタンスでは、 toArray()
を処理するのはList
インスタンスまでですので、できることはObject[]
を作成することだけです。それは、使用するより具体的なタイプのことを知らないだけです。これを見ているの
一つの方法は、List
sが彼らのタイプの一環として、型引数を持っているのに対し、およびオブジェクトクラスを持っていますが、変数は型を持っているので、配列は、そのクラスの一環として、型引数を持っているということです、オブジェクトを保持する変数からのみ、オブジェクトの型引数(List
)を取得することはできません(脇に、配列を保持する変数から配列の型引数を取得することはできません(考慮する)。しかし、それは本当に重要ではありません。なぜなら、変数はヌルでない限りオブジェクトを保持できるからです。
は、コードにこれを煮詰めるために、問題がある:
public <E> E[] createSimilarlyTypedArray(List<E> list) {
Class<E> componentType = list.???; // there is no way to do this
return Arrays.newInstance(componentType, list.size());
}
質問は分かりません。独自のメソッド'add(Animal ...) 'を作成しましたが、ArrayList.add(Object)を呼び出すのではなく、自分のものではありません。何故ですか?コードの文脈で質問を編集してください。あなたの'add 'メソッド内にそのコードブロックがありますか?あなたの唯一の問題は、Object []をAnimal []にキャストすることができないということなので、@Tom answerに従ってください。 – aalku
将来の注意:コンパイラエラーがある場合は、完全なエラーメッセージとこのメッセージに関連するソースコード行をコピーしてください。 –