不同的保留策略如何影响我的注释?
任何人都可以用清晰的方式解释java.lang.annotation.RetentionPolicy
常量SOURCE
, CLASS
和RUNTIME
之间的实际差异吗?
我也不完全确定“保留注释”是什么意思。
RetentionPolicy.SOURCE
:在编译期间丢弃。 这些注释在编译完成后没有任何意义,所以不会写入字节码。
例如:@Override
@SuppressWarnings
@Override
@SuppressWarnings
RetentionPolicy.CLASS
:在类加载期间丢弃。 在进行字节码级别的后期处理时很有用。 有点令人惊讶的是,这是默认的。
RetentionPolicy.RUNTIME
:不要丢弃。 注释应该在运行时可用于reflection。 例如:@Deprecated
来源:现在的旧url已经死了hunter_meta ,换成了hunter-meta-2-098036 。 如果这种情况发生,我正在上传页面的图像。
图像 (右键单击并select“在新选项卡/窗口中打开图像”)
根据你对类反编译的意见,这里是我认为它应该工作:
-
RetentionPolicy.SOURCE
:不会出现在反编译的类中 -
RetentionPolicy.CLASS
:出现在反编译的类中,但不能在运行时用getAnnotations()
进行reflection检查 -
RetentionPolicy.RUNTIME
:出现在反编译的类中,可以在运行时用getAnnotations()
进行reflection检查
最小的可运行示例
语言水平 :
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
没有得到任何注释。
GitHub上的例子让你玩。
保留策略:保留策略决定了注释在什么时候被丢弃。
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。