任何人都可以清楚地解释java.lang.annotation.RetentionPolicy
常量SOURCE
,CLASS
和RUNTIME
之间的实际差异吗?
我也不确定“保留注释”这个词是什么意思。
答案 0 :(得分:183)
RetentionPolicy.SOURCE
:弃牌期间 编译。这些注释没有 在编译之后有意义 完成了,所以他们不写 字节码。
示例:@Override
,@SuppressWarnings
RetentionPolicy.CLASS
:弃牌期间 类加载。这样做很有用 字节码级后处理。 有点令人惊讶的是,这就是 默认值。
RetentionPolicy.RUNTIME
:不要 丢弃。注释应该是 可用于运行时的反射。 示例:@Deprecated
<强>来源:强>
旧的URL现在已经死了
hunter_meta 并替换为hunter-meta-2-098036。如果这种情况发生了变化,我会上传页面图片。
Image(右键单击并选择“在新标签/窗口中打开图片”)
答案 1 :(得分:46)
根据你对类反编译的评论,我认为它应该如何工作:
RetentionPolicy.SOURCE
:不会出现在反编译类
RetentionPolicy.CLASS
:出现在反编译的类中,但无法在运行时使用[{1}}
getAnnotations()
:出现在反编译的类中,可以在运行时使用[{1}}
答案 2 :(得分:18)
最小可运行示例
语言水平:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.SOURCE)
@interface RetentionSource {}
@Retention(RetentionPolicy.CLASS)
@interface RetentionClass {}
@Retention(RetentionPolicy.RUNTIME)
@interface RetentionRuntime {}
public static void main(String[] args) {
@RetentionSource
class B {}
assert B.class.getAnnotations().length == 0;
@RetentionClass
class C {}
assert C.class.getAnnotations().length == 0;
@RetentionRuntime
class D {}
assert D.class.getAnnotations().length == 1;
}
字节码级别:使用javap
我们发现Retention.CLASS
带注释的类获得了RuntimeInvisible类属性:
#14 = Utf8 LRetentionClass;
[...]
RuntimeInvisibleAnnotations:
0: #14()
而Retention.RUNTIME
注释获得RuntimeVisible类属性:
#14 = Utf8 LRetentionRuntime;
[...]
RuntimeVisibleAnnotations:
0: #14()
并且Runtime.SOURCE
带注释的.class
没有获得任何注释。
答案 3 :(得分:4)
RetentionPolicy.SOURCE
:注释将在程序的源代码中提供,它既不在.class文件中,也不在运行时可用。由编译器使用。
RetentionPolicy.CLASS
:注释将在.class文件中,但在运行时不可用。由字节码操作工具(如ASM)使用,执行修改
RetentionPolicy.RUNTIME
:注释可以在.class文件和运行时获得,通过getAnnotations()
的java反射进行检查。
答案 4 :(得分:3)
保留策略:保留策略确定放弃注释的位置。
1.SOURCE: annotation retained only in the source file and is discarded
during compilation.
2.CLASS: annotation stored in the .class file during compilation,
not available in the run time.
3.RUNTIME: annotation stored in the .class file and available in the run time.
使用Java的内置注释指定保留策略:@Retention。
答案 5 :(得分:0)
@Retention
允许您定义注释的生命周期[About]
RetentionPolicy.SOURCE
:仅在编译器使用的源代码中可用。很好的例子是Java世界中的@Override
,@SuppressWarnings
和Android注释中的@IntDef
和@StringDef
RetentionPolicy.CLASS
:仅在.class
文件中可用。由一些工具代码生成,操纵,配置等使用。例如ASM framework或Jake Wharton和{{3}的Java AspectJ和Hugo之类的Java AOP范例},来自Fernando Cejas
RetentionPolicy.RUNTIME
:在.class
文件和运行时可用。您可以通过getAnnotations()
Java Reflection API来获取它。例如,匕首2的@Scope
注释
答案 6 :(得分:0)