Java注释-查找RetentionPolicy.CLASS的示例

Java注释-查找RetentionPolicy.CLASS的示例,java,annotations,Java,Annotations,根据Java注释API: 保留政策类 注释将由用户记录在类文件中 编译器,但不需要由 虚拟机在运行时运行 RetentionPolicy.RUNTIME 注释将由用户记录在类文件中 编译器,并在运行时由VM保留 时间,以便阅读 深思熟虑地 我正在寻找“类别”保留政策的样本。当我们需要使用此策略而不是运行时策略时。我在当前项目中拥有大量库。例如,我能找到的唯一例子就是在图书馆里 不过,我不太清楚他们为什么选择这种保留策略——可能是为了工具支持,工具本身读取类文件,而不是通过反射API。不过,我

根据Java注释API:

  • 保留政策类 注释将由用户记录在类文件中 编译器,但不需要由 虚拟机在运行时运行

  • RetentionPolicy.RUNTIME 注释将由用户记录在类文件中 编译器,并在运行时由VM保留 时间,以便阅读 深思熟虑地


我正在寻找“类别”保留政策的样本。当我们需要使用此策略而不是运行时策略时。

我在当前项目中拥有大量库。例如,我能找到的唯一例子就是在图书馆里


不过,我不太清楚他们为什么选择这种保留策略——可能是为了工具支持,工具本身读取类文件,而不是通过反射API。不过,我不确定我是否真的看到了这种区别的意义。

类注释用于像这样的模糊处理工具中。
例如,当您需要保持类名不变以便能够调用class.forName()之类的方法时,annotation@KeepName会禁用名称篡改

RetentionPolicy.CLASS在执行字节码级后处理时非常有用

示例:


最小示例

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;
}
如果我们在注释类上使用
javap
,我们会看到
Retention.CLASS
注释类获得一个CLASS属性:

#14 = Utf8               LRetentionClass;
[...]
RuntimeInvisibleAnnotations:
  0: #14()
#14 = Utf8               LRetentionRuntime;
[...]
RuntimeVisibleAnnotations:
  0: #14()
Retention.RUNTIME
注释获取一个类属性:

#14 = Utf8               LRetentionClass;
[...]
RuntimeInvisibleAnnotations:
  0: #14()
#14 = Utf8               LRetentionRuntime;
[...]
RuntimeVisibleAnnotations:
  0: #14()
因此,这两种情况下的信息都以字节码的形式存在

因此,
Runtime.CLASS
可用于将任意元数据关联到字节码操作工具可以使用的类,而不会干扰运行时可见的行为


供您使用。

如果我正在反编译具有注释的类
RetentionPolicy.class
(例如来自Guava的
@VisibleForTesting
),则注释不会显示在反编译的类文件中。但是根据javadoc,这种类型的注释记录在类文件中,那么为什么它没有显示在反编译的java文件中呢。有什么想法吗?