Java RetentionPolicy类与运行时

Java RetentionPolicy类与运行时,java,annotations,Java,Annotations,RetentionPolicy.CLASS和RetentionPolicy.RUNTIME之间的实际区别是什么 看起来两者都被记录到字节码中,并且在运行时都可以访问 无论如何,都可以在运行时访问这两者 这并不是政府所说的: 运行时:编译器将注释记录在类文件中,并在运行时由VM保留,因此可以反射地读取注释 类:编译器将注释记录在类文件中,但运行时VM不必保留注释 实际上,我不知道类的任何用例。只有当您希望以编程方式读取字节码,而不是通过ClassLoaderAPI读取字节码时,它才有用,但这是一种

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

看起来两者都被记录到字节码中,并且在运行时都可以访问

无论如何,都可以在运行时访问这两者

这并不是政府所说的:

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

类:编译器将注释记录在类文件中,但运行时VM不必保留注释

实际上,我不知道
类的任何用例。只有当您希望以编程方式读取字节码,而不是通过ClassLoaderAPI读取字节码时,它才有用,但这是一种非常特殊的情况,我不知道您为什么不直接使用
运行时

讽刺的是,
CLASS
是默认行为

看起来两者都被记录到字节码中,并且在运行时都可以访问

对于基本内置注释接口,如
getAnnotations
,则为False。例如:

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
注释类获得CLASS属性,而
Retention.RUNTIME
注释获得CLASS属性。这可以通过
javap
观察到


给你玩。

我当然读过了。听起来“不需要”并不排除“可能”,这就是问题的原因。@Dima:如果规范说实现不需要做某件事,那么假设它做了那件事是愚蠢的。假设没有,你一定是对的。不清楚的是,对于这个相当具体的案例,“实现不必做任何事情”一词的含义。至少在RetentionPolicy.CLASS的情况下,我假设实现必须将信息保存在字节码中。有什么能阻止我使用反射从字节码中提取它吗?如果是(将停止),那么“将信息保留在字节码中”的含义是什么?@Dima:如果直接读取字节码,您可以从字节码中提取信息。如果您使用反射API,它可能不在那里。这可能是正确的。不确定RetentionPolicy.CLASS的存在在这种情况下是否有意义。最初可能还有其他原因……在运行时,无法使用反射API访问see
类的可能副本。直接使用字节码操作的特殊库可以使用类注释。例如,BCEL-字节码工程库。请在此处阅读更多信息-