Java 字段#getAnnotations()和字段#getDeclaredAnnotations()之间的差异

Java 字段#getAnnotations()和字段#getDeclaredAnnotations()之间的差异,java,inheritance,annotations,Java,Inheritance,Annotations,JavaDoc说: : 返回此元素上直接存在的所有注释。与此接口中的其他方法不同,此方法忽略继承的注释。(如果此元素上没有直接的注释,则返回长度为零的数组。)此方法的调用方可以自由修改返回的数组;它对返回给其他调用者的数组没有影响 : 返回此元素上存在的所有批注。(如果此元素没有注释,则返回长度为零的数组。)此方法的调用方可以自由修改返回的数组;它对返回给其他调用者的数组没有影响 由于getAnnotations继承自类java.lang.reflect.AccessibleObject,因此具

JavaDoc说:

:

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

:

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

由于
getAnnotations
继承自类
java.lang.reflect.AccessibleObject
,因此具有字段对象访问它的权限


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

相反
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)
您可以看到
类getDeclaredAnnotations()
是空的,因为类Test3本身没有注释,只有从Test2继承的注释

从@Inherited的Javadoc:

指示注释类型是自动继承的。如果注释类型声明中存在继承的元注释,并且用户在类声明中查询注释类型,而该类声明中没有该类型的注释,则该类的超类将自动查询注释类型。将重复此过程,直到找到此类型的注释,或到达类层次结构(对象)的顶部。如果没有超类具有此类型的注释,那么查询将指示所讨论的类没有此类注释。请注意,如果注释类型用于注释类以外的任何内容,则此元注释类型无效。还要注意,这个元注释只会导致注释从超类继承;已实现接口上的注释无效


查看源代码可以得到答案:

摘录自:

因为:
getDeclaredAnnotations()
被调用

因此,在
java.lang.reflect.Field
对象上调用这两个方法时执行相同的操作。
(因此我认为JavaDoc是错误的)

另一种情况是覆盖这两种方法(并按照它所说的做):


getDeclaredAnnotations()仅在getAnnotations()从其父类提供直接实现的以及可继承的注释(@Inherited)的情况下提供直接实现的注释

这如何适用于
字段
?还有,OP说我在处理类的时候知道它是如何工作的,但我不知道这个字段。但是谢谢你指出我得到了忽略错误谢谢你更新了你的代码片段,但是我仍然看不出太多方法之间的区别。。。
/**
 * @since 1.5
 */
public Annotation[] getAnnotations() { 
    return getDeclaredAnnotations();
}

/**
 * @since 1.5
 */
public Annotation[] getDeclaredAnnotations()  {
    throw new AssertionError("All subclasses should override this method");
}
/**
 * @since 1.5
 */
public Annotation[] getAnnotations() { 
    initAnnotationsIfNecessary();
    return AnnotationParser.toArray(annotations);
}

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