23

JavaDoc は次のように述べています。

AccessibleObject#getDeclaredAnnotations :

この要素に直接存在するすべての注釈を返します。このインターフェースの他のメソッドとは異なり、このメソッドは継承された注釈を無視します。(この要素に注釈が直接存在しない場合、長さゼロの配列を返します。) このメソッドの呼び出し元は、返された配列を自由に変更できます。他の呼び出し元に返される配列には影響しません。

Field#getAnnotations :

この要素に存在するすべての注釈を返します。(この要素に注釈がない場合、長さゼロの配列を返します。) このメソッドの呼び出し元は、返された配列を自由に変更できます。他の呼び出し元に返される配列には影響しません。

getAnnotationsは class から継承されているためjava.lang.reflect.AccessibleObject、 Field オブジェクトにアクセスさせます。

getDeclaredAnnotations私が理解しているように、継承された注釈を無視するのはそれらの間の唯一の違いです。クラスを扱うときにそれを取得しますが、私が知る限り、フィールドは注釈を継承できません。

4

3 に答える 3

2

それは逆です。getDeclaredAnnotations()- ドキュメントが言うように - 継承された注釈を無視する唯一の方法です。

以下は、違いを示すスニペットです。

public class Test1 {
    public static void main(String[] args) {
        Test3 test = new Test3();

        for (Annotation annotation : test.getClass().getAnnotations()) {
            System.out.println("Class getAnnotations: " + annotation);
        }

        for (Annotation annotation : test.getClass().getDeclaredAnnotations()) {
            System.out.println("Class getDeclaredAnnotations: " + annotation);
        }

        for (Field field : test.getClass().getFields()) {
            for (Annotation annotation : field.getAnnotations()) {
                System.out.println("Field getAnnotations: " + annotation);
        }

        for (Annotation annotation : field.getDeclaredAnnotations()) {
            System.out.println("Field getDeclaredAnnotations: " + annotation);
        }
    }
}

@Retention(RetentionPolicy.RUNTIME)
@Inherited
@interface CustomAnnotation {
    String value();
}

@CustomAnnotation("Class")
class Test2 {
    @CustomAnnotation("Field") public String testString;
}

 class Test3 extends Test2 {} 

出力は `getAnnotations:

Class getAnnotations: @test.CustomAnnotation(value=Class)
Field getAnnotations: @test.CustomAnnotation(value=Field)
Field getDeclaredAnnotations: @test.CustomAnnotation(value=Field)

Class getDeclaredAnnotations()クラス Test3 にはアノテーション自体がなく、Test2 から継承されたアノテーションしかないため、が空であることがわかります。

@Inherited の Javadoc から:

注釈型が自動的に継承されることを示します。Inherited メタ注釈が注釈型宣言に存在し、ユーザーがクラス宣言で注釈型をクエリし、クラス宣言にこの型の注釈がない場合、クラスのスーパークラスは注釈型に対して自動的にクエリされます。このプロセスは、この型の注釈が見つかるか、クラス階層 (オブジェクト) の最上位に到達するまで繰り返されます。スーパークラスにこのタイプのアノテーションがない場合、クエリは、問題のクラスにそのようなアノテーションがないことを示します。注釈付きの型がクラス以外のものに注釈を付けるために使用されている場合、このメタ注釈型は効果がないことに注意してください。このメタアノテーションは、スーパークラスから継承されるアノテーションのみを引き起こすことにも注意してください。

于 2013-08-29T13:56:58.030 に答える