23

JavaDoc 说明如下:

AccessibleObject#getDeclaredAnnotations

返回此元素上直接存在的所有注释。与此接口中的其他方法不同,此方法忽略继承的注解。(如果此元素上没有直接存在注释,则返回长度为零的数组。)此方法的调用者可以自由修改返回的数组;它不会影响返回给其他调用者的数组。

字段#getAnnotations

返回此元素上存在的所有注释。(如果此元素没有注释,则返回长度为零的数组。)此方法的调用者可以自由修改返回的数组;它不会影响返回给其他调用者的数组。

由于getAnnotations是从 class 继承的java.lang.reflect.AccessibleObject,因此有 Field 对象可以访问它。

据我了解,这是它们之间唯一getDeclaredAnnotations忽略继承注释的区别。我在处理类时明白这一点,但据我所知,字段不能继承注释。

4

3 回答 3

12

查看源代码给出了答案:

摘自java.lang.reflect.AccessibleObject

/**
 * @since 1.5
 */
public Annotation[] getAnnotations() { 
    return getDeclaredAnnotations();
}

/**
 * @since 1.5
 */
public Annotation[] getDeclaredAnnotations()  {
    throw new AssertionError("All subclasses should override this method");
}

并且由于Field 没有覆盖getAnnotations():getDeclaredAnnotations()被调用。

所以这两种方法在java.lang.reflect.Field对象上调用时都是一样的。 (所以我认为 JavaDoc 是错误的)

另一种情况是java.lang.Class覆盖了这两种方法(并按照JavaDoc所说的那样做;)):

/**
 * @since 1.5
 */
public Annotation[] getAnnotations() { 
    initAnnotationsIfNecessary();
    return AnnotationParser.toArray(annotations);
}

/**
 * @since 1.5
 */
public Annotation[] getDeclaredAnnotations()  {
    initAnnotationsIfNecessary();
    return AnnotationParser.toArray(declaredAnnotations);
}
于 2013-08-29T15:00:56.103 回答
4

getDeclaredAnnotations() 仅在 getAnnotations() 提供直接实现的注释以及从其父类继承的注释(@Inherited)时才提供直接实现的注释。

于 2014-08-02T22:59:38.487 回答
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 回答