RetentionPolicy.CLASS
和RetentionPolicy.RUNTIME
之间的实际区别是什么?
看起来两者都记录在字节码中,无论如何都可以在运行时访问它们。
答案 0 :(得分:52)
无论如何都可以在运行时访问。
这不是javadoc所说的:
RUNTIME:注释将由编译器记录在类文件中,并且在运行时由VM保留,因此可以反射性地阅读。
CLASS:注释将由编译器记录在类文件中,但VM在运行时不需要保留 。
在实践中,我不知道CLASS
的任何用例。只有你想以编程方式读取字节码,而不是通过类加载器API,才会有用,但这是一个非常专业的案例,我不知道为什么你不会只使用RUNTIME
。
具有讽刺意味的是,CLASS
是默认行为。
答案 1 :(得分:2)
对于像看起来两者都记录在字节码中,无论如何都可以在运行时访问它们。
getAnnotations
这样的基本内置注释界面,为假。 E.g:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.CLASS)
@interface RetentionClass {}
@Retention(RetentionPolicy.RUNTIME)
@interface RetentionRuntime {}
public static void main(String[] args) {
@RetentionClass
class C {}
assert C.class.getAnnotations().length == 0;
@RetentionRuntime
class D {}
assert D.class.getAnnotations().length == 1;
}
所以观察RetentionPolicy.CLASS
注释的唯一方法是使用字节码解析器。
另一个区别是Retention.CLASS
带注释的类获得RuntimeInvisible类属性,而Retention.RUNTIME
注释获得RuntimeVisible类属性。这可以通过javap
来观察到。
答案 2 :(得分:0)
可以从类字节代码访问具有保留策略
CLASS
和RUNTIME
的注释。我们需要使用字节代码操作库(例如ASM)来访问字节代码中可用的Annotations。