RetentionPolicy CLASS与RUNTIME

Dim*_*ima 44 java annotations

RetentionPolicy.CLASS和之间有什么实际区别RetentionPolicy.RUNTIME

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

ska*_*man 53

无论如何都可以在运行时访问它们.

这不是javadoc所说的:

RUNTIME:注释将由编译器记录在类文件中,并在运行时由VM保留,因此可以反射性地读取它们.

CLASS:注释将由编译器记录在类文件中,但在运行时不需要由VM保留.

在实践中,我不知道任何用例CLASS.只有你想以编程方式读取字节码,而不是通过类加载器API,这才有用,但这是一个非常专业的案例,我不知道为什么你不会只使用它RUNTIME.

具有讽刺意味的是,CLASS是默认行为.

  • @Dima:如果直接读取字节码,可以从字节码中提取它.如果您使用反射API,它可能不会存在. (6认同)

Cir*_*四事件 7

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

对于基本的内置注释接口(如getAnnotations. 例如:

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;
}
Run Code Online (Sandbox Code Playgroud)

所以观察RetentionPolicy.CLASS注解的唯一方法是使用字节码解析器。

另一个区别是被Retention.CLASS注解的类得到一个RuntimeInvisible类属性,而Retention.RUNTIME注解得到一个RuntimeVisible类属性。这可以通过 观察到javap

GitHub 上的示例供您使用。