一、@Retention 简介 @Retention 是用来定义注解的注解,这类注解也叫 元注解。@Retention 定义了注解的生命周期,生命周期的长短取决于 RetentionPolicy
属性值。
1 2 3 4 5 6 7 8 9 10 @Documented @Retention (RetentionPolicy.RUNTIME)@Target (ElementType.ANNOTATION_TYPE)public @interface Retention { RetentionPolicy value () ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public enum RetentionPolicy { SOURCE, CLASS, RUNTIME }
归纳如下:
属性值
描述
使用场景
RetentionPolicy.SOURCE
注解只保留在源文件,当被编译成class文件,注解就会消失
代码预检,如 @Override、@SuppressWarnings
RetentionPolicy.CLASS
注解被保留到class文件,但当jvm加载class文件时被遗弃
编译时进行一些预处理操作,如生成辅助信息(META-INF/services)
RetentionPolicy.RUNTIME
注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在
运行时动态获取注解信息,如 @Autowired、@Required
二、通过字节码认识 @Retention 定义三种生命周期的注解:SourcePolicy、ClassPolicy、RuntimePolicy 1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Retention (RetentionPolicy.SOURCE)@Target (ElementType.METHOD)public @interface SourcePolicy {} @Retention (RetentionPolicy.CLASS)@Target (ElementType.METHOD)public @interface ClassPolicy {} @Retention (RetentionPolicy.RUNTIME)@Target (ElementType.METHOD)public @interface RuntimePolicy {}
使用以上注解:
1 2 3 4 5 6 7 8 9 10 11 12 13 public class RetentionPolicyTest { @SourcePolicy public void sourcePolicy () { } @ClassPolicy public void classPolicy () { } @RuntimePolicy public void runtimePolicy () { } }
javap -v RetentionPolicyTest
查看字节码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 { public RetentionPolicyTest () ; flags: ACC_PUBLIC Code: stack=1 , locals=1 , args_size=1 0 : aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4 : return LineNumberTable: line 3 : 0 public void sourcePolicy () ; flags: ACC_PUBLIC Code: stack=0 , locals=1 , args_size=1 0 : return LineNumberTable: line 7 : 0 public void classPolicy () ; flags: ACC_PUBLIC Code: stack=0 , locals=1 , args_size=1 0 : return LineNumberTable: line 11 : 0 RuntimeInvisibleAnnotations: 0: #11() public void runtimePolicy () ; flags: ACC_PUBLIC Code: stack=0 , locals=1 , args_size=1 0 : return LineNumberTable: line 15 : 0 RuntimeVisibleAnnotations: 0: #14() }
可以看到:
编译之后,@SourcePolicy 信息不存在;
编译之后,@ClassPolicy 具有属性:RuntimeInvisibleAnnotations;
编译之后,@RuntimePolicy 具有属性:RuntimeVisibleAnnotations;