2

リフレクション ポストを使用して Java でジェネリック パラメーターの型を取得することを読みましたが、それがどのように可能になるのか疑問に思いました。誰かが投稿したソリューションとコードを使用しました

List<Integer> l = new ArrayList<>();
Class actualTypeArguments = (Class) ((ParameterizedType) l.getClass().getGenericSuperclass()).getActualTypeArguments()[0];

しかし、これは私にはうまくいきません。

java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class

クラス キャストを削除すると、実際の引数の型は になりEます。これは List インターフェイスからの型定義です。

したがって、私の質問は、ここで何か間違ったことをしているのでしょうか? コンパイル時に型が消去されるはずなので、この動作は私が予想していたものですよね?

4

3 に答える 3

2

javadoc は、あなたが何をしているかを教えてくれます。

Class#getGenericSuperclass()状態

この Class によって表されるエンティティ (クラス、インターフェイス、プリミティブ型、または void) の直接のスーパークラスを表す Type を返します。

スーパークラスがパラメーター化された型である場合、返される Type オブジェクトは、ソース コードで使用される実際の型パラメーターを正確に反映する必要があります。[...]

の直接のスーパークラスはArrayListですAbstractList。宣言はソースコードでそのままです

public class ArrayList<E> extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable

したがって、Typeそれによって返されたオブジェクトを印刷すると、

java.util.AbstractList<E>

したがって、ParameterizedType#getActualTypeArguments()どの状態

この型への実際の型引数を表す Type オブジェクトの配列を返します。

を返しますType

E

以来、クラス定義Eで使用される実際の型引数です。ArrayList

于 2013-11-08T13:47:30.247 に答える
1

説明した方法は、継承のためにジェネリック型が設定されている場合にのみ機能します。これは、コンパイル時に既知であるためです。

 public class SomeClass<T>{

 }

 public class SpecificClass extends SomeClass<String>{

 }

この例では、メソッドを使用すると、「String.class」が返されます。

その場でインスタンスを作成している場合、それは機能しません:

SomeClass s = new SomeClass<String>(); //wont work here.

いくつかの一般的な回避策は、後で参照できるように実際のクラスをパラメーターとして渡すことです。

 public class SomeClass<T>{
    Class<T> clazz

    public SomeClass(Class<T> clazz){
        this.clazz = clazz;
    }

    public Clazz<T> getGenericClass(){
       return this.clazz;
    } 
 }

利用方法:

 SomeClass<String> someClass= new SomeClass<String>(String.class);

 System.out.println(someClass.getGenericClass()) //String.class

実際には、このようなシナリオではジェネリック型は必要ありません.Javaは、「T」をObject. 唯一の利点は、T のゲッターとセッターを定義でき、常にオブジェクトを型キャストする必要がないことです。(Java がそれを行っているため) (Type Erasure と呼ばれます)

于 2013-11-08T13:44:48.680 に答える