web-dev-qa-db-ja.com

リフレクションを使用して注釈クラス名、属性値を取得する方法

注釈クラスを知っていれば、特定の注釈を簡単に取得してその属性にアクセスできます。例えば:

field.getAnnotation(Class<T> annotationClass) 

特定の注釈インターフェイスの参照を返すため、その値に簡単にアクセスできます。

私の質問は、特定のアノテーションクラスに関する予備知識がないかどうかです。クラス情報をたとえばjsonファイルとしてダンプする目的で、リフレクションを使用して実行時にすべての注釈クラス名とその属性を取得したいだけです。どうすれば簡単にできますか。

Annotation[] field.getAnnotations();

このメソッドは、注釈インターフェイスの動的プロキシのみを返します。

31
Jianwu Chen

予想されるものとは反対に、アノテーションの要素は属性ではありません。実際には、提供された値またはデフォルト値を返すメソッドです。

アノテーションのメソッドを繰り返し処理し、それらを呼び出して値を取得する必要があります。 annotationType()を使用して注釈のクラスを取得します。getClass()によって返されるオブジェクトは単なるプロキシです。

以下は、すべての要素とその値を出力する例です @Resource クラスの注釈:

@Resource(name = "foo", description = "bar")
public class Test {

    public static void main(String[] args) throws Exception {

        for (Annotation annotation : Test.class.getAnnotations()) {
            Class<? extends Annotation> type = annotation.annotationType();
            System.out.println("Values of " + type.getName());

            for (Method method : type.getDeclaredMethods()) {
                Object value = method.invoke(annotation, (Object[])null);
                System.out.println(" " + method.getName() + ": " + value);
            }
        }

    }
}

出力:

Values of javax.annotation.Resource
 name: foo
 type: class Java.lang.Object
 lookup: 
 description: bar
 authenticationType: CONTAINER
 mappedName: 
 shareable: true

Aaron に感謝します。警告を避けるために、null引数をキャストする必要があることを指摘してください。

67
kapex

上記の回答をフォローアップするだけです(返信するのに十分な担当者がいません):

method.invoke(annotation, null)

次のように変更する必要があります。変更しないと、例外がスローされます。

method.invoke(annotation, (Object[])null) or method.invoke(annotation, new Object[0])
13
Aaron