RetentionPolicy CLASS与RUNTIME

时间:2011-05-11 22:12:11

标签: java annotations

RetentionPolicy.CLASSRetentionPolicy.RUNTIME之间的实际区别是什么?

看起来两者都记录在字节码中,无论如何都可以在运行时访问它们。

3 个答案:

答案 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来观察到。

Examples on GitHub让你玩。

答案 2 :(得分:0)

  

可以从类字节代码访问具有保留策略CLASSRUNTIME的注释。我们需要使用字节代码操作库(例如ASM)来访问字节代码中可用的Annotations。

这里的简单示例 - http://bethecoder.com/applications/tutorials/java/annotations/class-and-runtime-retention-policy.html