2016-07-21 1 views
-1

多くの人がこれをやりたいと思っています。今、私はそれをやろうとしていますが、立ち往生しています。Java - 文字列型の名前からその型のArrayListを初期化する方法

言って、私はこのような方法があります:

private Object getList(String nameofType) { 
    return new ArrayList<Type>(); 
/**e.g. It returns ArrayList<java.lang.Double> if nameofType is "java.lang.Double", 
/*ArrayList<java.io.File> if nameofType is "java.io.File"**/ 
} 

は、どのように私はこのようなArrayListのを初期化することができますか?

+1

我々はJavaで_type erasure_を持っています。これは、実行時にジェネリック型のパラメータ型がわからないことを意味します。その結果、 'List 'と 'List 'は同じです。そのために文字列型のメソッドパラメータを持つ必要はありません。 – Seelenvirtuose

答えて

1

あなたがやりたいことに近いものは、このかもしれません有効な型チェックリストが返されます。指定された型と異なる型のオブジェクトを挿入しようとすると例外がスローされます。
あなたはそれ4を自分でチェックすることができます。

List list = getList("java.lang.Integer"); 
    System.out.println("Inserting Integer"); 
    list.add(new Integer(1)); 
    System.out.println("List: "+ list); 
    System.out.println("Inserting Long"); 
    list.add(new Long(1)); 
    System.out.println("List: "+ list); 

出力:ジェネリックを扱うとき

Inserting Integer 
List: [1] 
Inserting Long 
Exception in thread "main" java.lang.ClassCastException: Attempt to insert class java.lang.Long element into collection with element type class java.lang.Integer 
+0

Ah! 'privateリストgetList(String nameofType){ リストリスト= null; { クラスclazz = Class.forName(nameofType); //完全修飾でなければなりません。例: "java.lang.Integer" list = Collections.checkedList(new ArrayList()、clazz); } catch(ClassNotFoundException e){ //ログ例外など } リターンリスト; } ' これは私が必要なものです!ありがとうwalen! – sribasu

+0

もちろん、結果を 'ArrayList'に代入することはできません。 – Holger

+0

@Holger' List myList'インターフェースを使ってリストを宣言するのは良い方法です。そうすれば、あなたが望むどんなリストフレーバー(LinkedList、ArrayList、またはVector)でも使えますし、多くのコードを改造する必要はありません。あなたが絶対に必要とするならば、常に '(ArrayList)'にキャストできますが、少なくとも与えられた例のように 'Object'を返すわけではありません。 – walen

0

文字列パラメータを使用する必要がありますか?

ない場合は、ジェネリックを使用することができます。

private <T> Object getList(Class<T> listType) { 
    return new ArrayList<T>(); 
} 
+0

残念ながら 'はい'です。 – sribasu

0

ないあなたが達成しようとしているが、このコードは、あなたのニーズは、私はそれが正しくList<T>がオンに基づいて、返し

public <T> List<T> getList(Class<T> clazz) { 
    return new ArrayList<T>(); 
} 

信じる満たすものを確認してくださいそのパラメータに渡すクラスです。

パラメータとして文字列を使用しても、実際にはコンパイラは役に立ちません。実行時(https://docs.oracle.com/javase/tutorial/java/generics/erasure.html)にパラメーター化された型(ジェネリックを使用)の型情報が消去されることに注意してください。

+0

なぜ 'clazz'を渡すのですか?あなたはそれを使用していません... – Reimeus

+0

'T 'をバインドするには –

+0

宣言された型はそうしませんか? – Reimeus

2

(これは本当に質問に答えていないが、それだけで他の回答で提案されているようにClass<T>パラメータは、一般的なリストを作成するだけで不必要であることを指摘された)

グアバのLists.newArrayList方法は次のようになりますこれは:

public static <T> ArrayList<T> newArrayList() { 
    return new ArrayList<>(); 
} 

タイプパラメータは必要ありません。

List<String> stringList = Lists.newArrayList(); 
List<Integer> integerList = Lists.newArrayList(); 

あなたは、特定のタイプのために起動する必要がある場合は、呼び出すことができますように:

private List getList(String nameofType) { 
    List list = null; 
    try { 
     Class clazz = Class.forName(nameofType); //must be fully qualified, example: "java.lang.Integer" 
     list = Collections.checkedList(new ArrayList(), clazz); 
    } catch (ClassNotFoundException e) { 
     // log exception, etc. 
    } 
    return list; 
} 

Lists.<MySpecificType>newArrayList(); 
+0

あなたは問題を抱えています。私はリフレクションを使って汎用ユーティリティを書いています。私は、そのsetterメソッドを呼び出すことによって、BeanのArrayList型属性を設定する必要があります。 ListはArrayList なので、そのsetterメソッドは本質的にArrayList を期待しています。私は動的にArrayList を初期化しようとしていて、それをBeanに設定しました。あなたはタイプ消去が救世主だと言うとき、私はこのシナリオにも気にする必要はありませんか?つまり、新しいArrayListを作成し、それをReflectionを使用してメソッドにパラメータとして渡すことはできますか? – sribasu

+0

@sribasu: 'List'に' String's以外のものが含まれていないことを確認してください。 – Holger

関連する問題