2

指定された型を返すメソッドがあります。

T foo(Class<T> valueType) {...};

String s = foo(Java.lang.String.class);

クラスとしてジェネリック型を送信しようとしていますが、コンパイラ エラーが発生します。たとえば、文字列の ArrayList を返したいとします。

ArrayList<String> list = foot(ArrayList<String>.class)

パラメータ「文字列」がエラーを引き起こしています。返すジェネリック型を指定できる方法はありますか?

4

5 に答える 5

1

ランタイムclassフィールドの値は、適用するジェネリック型に依存せず、この構文は不正です。詳細はこちら

于 2012-12-05T19:46:17.010 に答える
0

ここで静的型のみに関心があると仮定すると、次のトリックが役立つ場合があります。

@SuppressWarnings("unchecked")
public static <T>
Class<T> appropriateClass(T... args) {
    return (Class<T>) args.getClass().getComponentType();
}

Class<ArrayList<String>> c = appropriateClass();
ArrayList<String> list = foo(c);

実際、私はそのトリックをあまり誇りに思っていません。しかし、あなたはそれを試してみたいかもしれません.

テストする場合:

System.out.println(c); // prints "class java.util.ArrayList"

したがって、 のような醜いキャストと同等(Class<ArrayList<String>>) (Class<?>) ArrayList.classです。

ArrayList<String>実行時と実行時に実際に異なるトークンが必要な場合は、Sean Patrick Floyd が言及しArrayListた手法を使用する必要があります。TypeToken

于 2012-12-07T22:00:12.570 に答える
0

メソッドの入力または出力をキャストするだけです。

ArrayList<String> list = foot((Class<ArrayList<String>>)(Class<?>)ArrayList.class);

また

ArrayList<String> list = (ArrayList<String>)foot(ArrayList.class);

基本的に、Classジェネリックはコンパイル時に機能するのに対し、ジェネリックは実行時のものを表すため、クラスはジェネリックとうまく機能しません。実行時には、プログラム内にクラス オブジェクトが 1 つだけ存在しますArrayListClass<ArrayList<String>>またはClass<ArrayList<Integer>>またはと呼んでClass<ArrayList>も、同じ単一のオブジェクトです。では、どのタイプにすればよいのでしょうか。すべてに有効な単純な答えはありません。

Java 言語は、クラス リテラルArrayList.classが type だけを持つべきであると判断しましたClass<ArrayList>。しかし、 type の式が必要な場合は問題が発生するClass<ArrayList<String>>ため、型を曲げる必要があります。

于 2012-12-05T22:43:17.203 に答える
0

これはあなたのために働きますか(編集済み)?

ArrayList list = foot(ArrayList.class)
于 2012-12-05T19:47:32.643 に答える
0

Type Erasure は醜い頭をもたげます。<…&gt;基本的に、Java はジェネリック句をコンパイル時にチェックし、実行時オブジェクトから消去して情報を永久に失います。厄介ですよね?メタオブジェクトは実行時に参照されるため.class、消去の影響も受けます。

ArrayList<String>.classコンパイル時に消去されますArrayList.class

ジェネリクスでタイプ セーフが必要な場合は、2 つのパラメーターを渡す必要があります。

ArrayList<String> foo = foot(ArrayList.class, String.class)

于 2012-12-07T22:20:39.113 に答える