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-字节码工程库。请在此处阅读更多信息-