考虑一下Java批注:
public @interface AnAnnotaton {}
带有此注释的类:
@AnAnnotaton
class AnAnnotatedClass{}
还有一个测试,检查类中是否存在此批注:
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;import java.lang.annotation.Annotation;
import org.junit.Test;public class AnAnnotationTest {@Testpublic void testAnAnnotation() throws Exception {AnAnnotatedClass anAnnotatedClass = new AnAnnotatedClass();Annotation[] annotationsOnClass = anAnnotatedClass.getClass().getAnnotations();assertThat(annotationsOnClass.length, is(1));}}
听起来是合理的权利,由于该类的确具有AnAnnotation注释,因此可以期望上述测试通过。
但是,此测试失败,原因是…
注释上缺少一个元注释(@Retention),它指示该注释将保留多长时间,如果上述注释按如下所述更改,则测试将按预期进行。
@Retention(RetentionPolicy.RUNTIME)
public @interface AnAnnotaton {}
那么@Retention的作用是-引用Javadoc:
指示注释类型的注释将保留多长时间。 如果注释类型声明上没有保留注释,则保留策略默认为RetentionPolicy.CLASS
有三种不同的保留政策:
1. SOURCE –注释由编译器删除
2. CLASS –注释存在于字节码中,但在运行时不存在,因此在尝试以反射方式确定类是否具有注释时不可用。 3.运行时–注释保留在字节码中,并且在运行时可用,因此可以在类上反射地找到。
这就是为什么当注释定义更改为包括@Retention(RetentionPolicy.RUNTIME)时,测试现在可以运行的原因。
基本的东西,但容易错过。
参考: Java注释 -all 和杂物博客上的JCG合作伙伴 Biju Kunjummen 保留的内容 。
翻译自: https://www.javacodegeeks.com/2012/09/java-annotations-retention.html