5

list.toArray(T[] a)T、 「ランタイム型」の 場合はどうなりますか?

" List" Java のインターフェース、メソッド: T[] toArray(T[] a)
OK、それはかなり古い質問です。通常、次のように使用します。

String[] array = list.toArray(new String[0]);
String[] array = list.toArray(new String[list.size()]);

私の問題は、コーディング時に「T」型が何であるかわからないことです。型「T」は実行時にのみ決定できます。例を次に示します。

List list=...;  // no generic type declared on this List
Class<?> clazz=...; //yeah, this is the real type of the element of the list, I can sure about that

ここで、要素の型が clazz である配列にリストを変換する必要があります。どうすればよいですか?

なぜこの種の必要性があるのか​​ 疑問に思っているかもしれません
.Morphia(これはjava-mongoDBフレームワークです)に少し変更を加えています. mongoDB からデータを取得し、POJO の右側のフィールドに設定する必要があります。特定の状況では、フィールド タイプは配列であり、取得されるデータは BasicDBList エンティティ (ArrayList を拡張する) であるため、BasicDBList エンティティは、POJO フィールドと互換性のあるタイプの配列に変換する必要がありました。

ArrayList のソース コードを調べた後、醜いコードで目標を達成しました。

List list=...;
Class<?> clazz=...;
Object targetArray=Array.newInstance(clazz, list.size());
list.toArray((Object[])targetArray);

これを行うためのより良い方法はありますか?

4

2 に答える 2

5

タイプが実行時にのみ認識される場合、ここで解決策はありません。

Java Genericsはコンパイル時のチェックであり、実行時に実際には存在しません。これは型消去と呼ばれますhttp://docs.oracle.com/javase/tutorial/java/generics/erasure.html

ランタイム環境がそのようなチェックを行わないことを意味します(たとえば、一般的に文字列として入力されたリストに整数を入れることができ、Object o = list.get(0)を使用すると問題なく実行されます)

ジェネリックスの本当のポイントは、コーディングエラーを防ぐためにコンパイル時チェックを提供することです

于 2012-11-13T04:01:03.607 に答える
1

コメントで @arne.b の助けを借りて、これを行うより良い方法はないと思います:

List list=...;
Class<?> clazz=...;
Object[] targetArray=(Object[])Array.newInstance(clazz, list.size());
Object[] myArray=list.toArray(targetArray);

次に、エラーなしでフィールドに設定できます。

Field field=...;    //ComponentType of this field can be sure is "clazz"
field.set(entity,myArray);

または、手動で実際の型に変換するためにこれを行うことができます:

Class<?> arrayClazz=Class.forName("[L"+clazz.getName()+";");
arrayClazz.cast(myArray);
于 2012-11-22T09:39:22.630 に答える