考虑一下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 {
@Test
public 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)时,测试现在可以运行的原因。
基本的东西,但容易错过。
翻译自: https://www.javacodegeeks.com/2012/09/java-annotations-retention.html