当注释存在时,为什么 `getDeclaredAnnotations()` 返回空列表?

joh*_*dav 4 java reflection language-lawyer

Javadocs条目getDeclaredAnnotations说明如下:

返回直接出现在该元素上的注释。此方法忽略继承的注释。如果此元素上没有直接存在注释,则返回值是长度为 0 的数组。此方法的调用者可以自由修改返回的数组;它不会影响返回给其他调用者的数组。

所以,我希望这个函数在 上返回一个长度为 1 的数组doSometing,然而,它返回一个长度为 0 的数组。为什么?getAnnotation对于相关类型也返回null.

MCVE:

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

public class AnnotationTest{

    public static void main(String[] args){
        Class<?> clazz = AnnotationTest.class;
        for(Method method : clazz.getMethods()){
            System.out.println(method.getName() + ":");
            for(Annotation annotation : method.getDeclaredAnnotations()){
                System.out.println(" - " + annotation.annotationType().getName());
            }
            System.out.println();
        }
    }

    @ExampleAnnotation
    public void doSomething(){}

    public @interface ExampleAnnotation{}

}
Run Code Online (Sandbox Code Playgroud)

实际 MCVE 输出:

main:

doSomething:

wait:

wait:

wait:

equals:

toString:

hashCode:
 - jdk.internal.HotSpotIntrinsicCandidate

getClass:
 - jdk.internal.HotSpotIntrinsicCandidate

notify:
 - jdk.internal.HotSpotIntrinsicCandidate

notifyAll:
 - jdk.internal.HotSpotIntrinsicCandidate
Run Code Online (Sandbox Code Playgroud)

预期 MCVE 输出:

// irrelevant method entries aren't shown

doSomething:
 - AnnotationTest.ExampleAnnotation

// irrelevant method entries aren't shown
Run Code Online (Sandbox Code Playgroud)

Swe*_*per 6

根据 Java 语言规范\xc2\xa79.6.4.2

\n
\n

如果T没有m对应于 的(元)注释java.lang.annotation.Retention,那么 Java 编译器必须将T其视为确实具有m值为 的元素的元注释java.lang.annotation.RetentionPolicy.CLASS

\n
\n

ExampleAnnotation没有@Retention元注释,因此它仅保留在类文件中。但是,它必须在运行时保留,以便通过反射进行访问。来自以下文档RetentionPolicy.RUNTIME

\n
\n

注解将由编译器记录在类文件中,并在运行时由VM保留,因此可以反射性地读取它们

\n
\n

将其与 的描述进行比较CLASS

\n
\n

注释将由编译器记录在类文件中,但 VM 在运行时不需要保留

\n
\n

ExampleAnnotation因此,为了获得所需的输出,您应该这样声明:

\n
@Retention(RetentionPolicy.RUNTIME)\n@interface ExampleAnnotation{}\n
Run Code Online (Sandbox Code Playgroud)\n