Retention(保留)注解说明,这种类型的注解会被保留到那个阶段. 有三个值:
1.RetentionPolicy.SOURCE —— 这种类型的Annotations只在源代码级别保留,编译时就会被忽略
2.RetentionPolicy.CLASS —— 这种类型的Annotations编译时被保留,在class文件中存在,但JVM将会忽略
3.RetentionPolicy.RUNTIME —— 这种类型的Annotations将被JVM保留,所以他们能在运行时被JVM或其他使用反射机制的代码所读取和使用.
public enum RetentionPolicy {
SOURCE,
CLASS,
RUNTIME
}
通过一个例子去验证一下。我定义了不同策略的注解去注解了三个方法
@Retention(RetentionPolicy.SOURCE)
public @interface SourceLevel {
}
@Retention(RetentionPolicy.CLASS)
public @interface ClassLevel {
}
@Retention(RetentionPolicy.RUNTIME)
public @interface RuntimeLevel {
}
public class Test {
@SourceLevel
public void sourceLevel(){}
@ClassLevel
public void classLevel(){};
@RuntimeLevel
public void runtimeLevel(){};
}
通过javap获取到Test类的字节码
public void sourceLevel();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=0, locals=1, args_size=1
0: return
LineNumberTable:
line 5: 0
public void classLevel();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=0, locals=1, args_size=1
0: return
LineNumberTable:
line 7: 0
RuntimeInvisibleAnnotations:
0: #11()
public void runtimeLevel();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=0, locals=1, args_size=1
0: return
LineNumberTable:
line 9: 0
RuntimeVisibleAnnotations:
0: #14()
可以看到
1. 编译器并没有记录下sourceLevel方法的注解信息
2. 编译器分别使用了RuntimeInvisibleAnnotations和RuntimeVisibleAnnotations属性去记录了classLevel和runtimeLevel的注解信息