如何在Java中获取类的注释?

47

我创建了自己的注解类型,就像这样:

public @interface NewAnnotationType {}

并将其附加到一个类中:

@NewAnnotationType
public class NewClass {
    public void DoSomething() {}
}

我试图通过反射获取类的注释,代码如下:

Class newClass = NewClass.class;

for (Annotation annotation : newClass.getDeclaredAnnotations()) {
    System.out.println(annotation.toString());
}

但是它没有打印任何东西。我做错了什么?


1
除非明确标注,否则注释仅在编译时可用。 - Thorbjørn Ravn Andersen
2个回答

56

默认的保留策略是RetentionPolicy.CLASS,这意味着默认情况下,注解信息不会在运行时被保留:

编译器将注解记录在类文件中,但虚拟机在运行时不需要保留。这是默认行为。

相反,使用RetentionPolicy.RUNTIME

编译器将注解记录在类文件中,并且虚拟机在运行时保留,以便可以通过反射读取它们。

...您可以使用@Retention元注释来指定:

@Retention(RetentionPolicy.RUNTIME)
public @interface NewAnnotationType {
}

如果我想使用外部jar包中的注解类型怎么办?我尝试了相同的方法,但是没有成功。即使将RetentionPolicy设置为SOURCE也没有帮助。有什么想法吗? - John Smith
你为什么认为使用 RetentionPolicy.SOURCE 会有所不同呢?JavaDoc 明确表示这意味着 "注释将被编译器丢弃"。无论如何,您需要进一步阐述确切的问题设置;我不明白使用外部 JAR 有什么区别。这可能最好在一个新的、单独的问题中提问。 - Matt Ball

0

拥有注解的默认 Retention不意味着在运行时无法读取它。

由于

编译器应该将注解记录在类文件中,但不需要在运行时保留。 这是默认行为。

可以通过直接读取 .class 文件访问它们


可以通过使用ASM库来实现(当然要处理一些边角情况)。

请查看其优秀的用户指南。特别是第4.2节注释。


您可能需要参考Spring框架对这些注解的处理(它使用了shaded asm依赖项):


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接