4

次のJavaコードについて考えてみます。

public class Test
{
    private Foo< String, String > foo1;
    private Foo< Integer, Integer > foo2;
}

public class Foo< T, V >
{
    private Bar< V > bar;
    private T a;
}

public class Bar< T >
{
    @MyAnnotation
    private List< T > list;
}

まず、「Test」という名前のクラスから始めて、「MyAnnotation」で注釈が付けられ、タイプが「java.lang.Collection」から派生しているすべてのフィールドを再帰的に検索します。与えられた例では、結果は次のようになります。

  • Test.foo1.bar.list
  • Test.foo2.bar.list

最初の要素はその要素の文字列のみを取得できるのに対し、2番目の要素は整数のみを取得できることは明らかです。

私の質問は次のとおりです。「MyAnnotation」で注釈が付けられたすべてのコレクションフィールドを見つけて、それらの要素タイプを伝えるための最良の(最も簡単な)方法は何ですか?

タイプjava.lang.Collectionから注釈付きフィールドを見つけることは問題ではありません。しかし、どのようにして、与えられた例に対して次のような結果を得ることができますか?

  • Test.foo1.bar.list<文字列>
  • Test.foo2.bar.list<整数>

私はいくつかのアプローチを試しましたが、コレクションの要素タイプとして「String」ではなく「Object」が常に表示されていました。

私は本当にこれに固執しています。よろしくお願いします!

4

2 に答える 2

11

あなたはこのように試すことができるかもしれません:

Field field = Test1.class.getField("list");

Type genericFieldType = field.getGenericType();

if(genericFieldType instanceof ParameterizedType){
    ParameterizedType aType = (ParameterizedType) genericFieldType;
    Type[] fieldArgTypes = aType.getActualTypeArguments();
    for(Type fieldArgType : fieldArgTypes){
        Class fieldArgClass = (Class) fieldArgType;
        System.out.println("fieldArgClass = " + fieldArgClass);
    }
}

これは戻りますfieldArgClass = java.lang.String

于 2012-06-08T09:20:59.150 に答える
0

これは、Javaの型消去のために不可能です。コンパイルすると、ジェネリック型はraw型に置き換えられ、次のようになります。

public class Test
{
    private Foo foo1;
    private Foo foo2;
}

public class Foo
{
    private Bar bar;
    private Object a;
}

public class Bar
{
    @MyAnnotation
    private List list;
}

次に、実際のタイプは、直接作業している場所に入力されfoo1ますfoo2。たとえば、次のコードです。

Test test = new Test();
List<String> a = test.foo1.bar;
String b = a.get(0);
Integer b = test.foo2.a;

次のようなものに翻訳されます:

Test test = new Test();
// The generic type is erased here...
List a = test.foo1.bar;
// ...and a cast is added here
String b = (String) a.get(0);
Integer b = (Integer) test.foo2.a;

簡単に言うと、コンパイル時に破棄されるため、その型を取得する方法はありません。

于 2012-06-08T09:54:50.913 に答える