3

単に:

public static class MyClass<T> {
    // i don't want to keep an instance of T, if it is not necessary.
    // and it is not nice, not neat.

    // Or, let's say, the member are in the form of :
    ArrayList<T> mArrayList = new ArrayList<T>();
    // the problem of getting the generic type parameter is still present.
}

@Test
public final void test() {
    MyClass<Integer> myObject = new MyClass<Integer>();
    getParamType( myObject );
}

private static final <T> void getParamType(final MyClass<T> _myObject) {
    System.out.println(_myObject.getClass().getTypeParameters()[0]);    // T
    System.out.println(((T) new Object()).getClass());                  // class java.lang.Object
}

コードを印刷するにはどうすればよいclass java.lang.Integerですか?

私はかなりの数のstackoverflowスレッドがこれについて尋ねている(そして答えている)ことを知っています。しかし、彼らはこの問題を解決できませんでした。

  • getGenericSuperclass()この単純なケースには継承が含まれていないため、なぜ呼び出す必要があるのか​​ わかりません。
  • そして、私もそれをキャストすることはできませんParameterizedType

.

System.out.println((ParameterizedType) _myObject.getClass());
// Compile Error: Cannot cast from Class<capture#11-of ? extends TreeTest2.MyClass> to ParameterizedType

System.out.println((ParameterizedType) _myObject.getClass().getGenericSuperclass());
// Runtime Exception: java.lang.ClassCastException

@Thomas のガイドに基づいて、回避策を取得する方法を見つけましclass java.lang.Integer

まず、テスト コードで匿名(匿名である必要があります) のサブクラスを作成します。MyClass<T>(これは奇妙です。なぜサブクラスしかサポートしないのですか?)

@Test
public final void test() {
    MyClass<Integer> myObject = new MyClass<Integer>() {};  // Anonymous sub-class
    getParamType( myObject );
}

getGenericSuperclass()次に、メソッドを使用してを取得しType、キャストしてからParameterizedTypeを使用できgetActualTypeArguments()ます。

private static final <T> void getParamType(final MyClass<T> _myObject) {
    System.out.println( ((ParameterizedType) _myObject.getClass().getGenericSuperclass()).getActualTypeArguments()[0] );
}

それは完全に印刷されclass java.lang.Integerます。

テスト コードは実際の状況をシミュレートする必要があり、ユーザーが無意味なサブクラスを作成し続けることはないため、これはあまり良くありません。

このアプローチは、TypeReference クラスの考え方に基づいています。しかし、私はそれを使用する方法を本当に知りません。私は試しclass MyClass<T> extends TypeReference<T>ました。しかし、私はまだprintMyClass<T>を持つサブクラスを作成する必要があります。TypeReference.getType()class java.lang.Integer

最善のアプローチはまだここにないので、助けてください。


上記の回避策に基づく追加の質問:なぜ匿名サブクラスのみが機能するのですか?

public static class SubMyClass<T> extends MyClass<T>{}

@Test
public final void test() {
    MyClass<Integer> myObject = new MyClass<Integer>() {};  // Anonymous sub-class
    getParamType( myObject );               // class java.lang.Integer

    MyClass<Integer> mySubObject = new SubMyClass<Integer>();   // named sub-class
    getParamType( mySubObject );            // T
}

(MyClassそしてgetParamType()変わらない。)

4

4 に答える 4

1

Javaには、 Type Erasureと呼ばれる見当違いの機能があり、特にそれを防ぐことができます。

ジェネリック パラメータ情報は、実行時には存在しません。

代わりに、手動でClass<T>.

于 2013-08-20T14:24:24.007 に答える
0

の値を知るには、TMyClass をサブクラス化して型定義に取り込む必要があります。

class MyStringClass extends MyClass<String> {}

必要に応じて、匿名クラスでこれを行うこともできます。

MyClass<String> myStringClass = new MyClass<String>{}();

T の値を解決するには、TypeToolsを使用できます。

Class<?> stringType = TypeResolver.resolveRawArgument(MyClass.class, myStringClass.getClass());
assert stringType == String.class;
于 2013-10-26T02:39:02.613 に答える