Java 不同的保留策略如何影响我的批注?
谁能清楚地解释一下Java 不同的保留策略如何影响我的批注?,java,annotations,Java,Annotations,谁能清楚地解释一下java.lang.annotation.RetentionPolicy常量源代码、类和运行时之间的实际区别 我也不太清楚“保留注释”这个短语是什么意思 RetentionPolicy.SOURCE:在 编译。这些注释不存在 编译完成后是否有意义 已完成,因此它们不会被写入 字节码。 示例:@Override,@SuppressWarnings RetentionPolicy.CLASS:在 课堂负荷。做某事时有用 字节码级后处理。 有点令人惊讶的是,这是 默认 Retent
java.lang.annotation.RetentionPolicy
常量源代码、类和运行时之间的实际区别
我也不太清楚“保留注释”这个短语是什么意思
RetentionPolicy.SOURCE
:在
编译。这些注释不存在
编译完成后是否有意义
已完成,因此它们不会被写入
字节码。
示例:@Override
,@SuppressWarnings
RetentionPolicy.CLASS
:在
课堂负荷。做某事时有用
字节码级后处理。
有点令人惊讶的是,这是
默认
RetentionPolicy.RUNTIME
:不
丢弃。注释应该是
可在运行时进行反射。
示例:@已弃用
来源:
旧的URL现在已经死了
并替换为。如果这一点发生了,我会上传页面的图像
(右键单击并选择“在新选项卡/窗口中打开图像”)
根据您对类反编译的评论,以下是我认为它应该如何工作:
RetentionPolicy.SOURCE
:不会出现在反编译类中
RetentionPolicy.CLASS
:出现在反编译类中,但不能在运行时使用getAnnotations()进行反射检查
RetentionPolicy.RUNTIME
:出现在反编译类中,可以在运行时使用getAnnotations()进行反射检查
最小可运行示例
语言级别:
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
注释类获得一个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()
带注释的.class
运行时.SOURCE
不会得到任何注释
供您使用。保留策略:保留策略决定在何时丢弃批注。它是使用Java的内置注释指定的:@Retention
- 课程
:编译器将注释记录在类文件中,但VM不需要在运行时保留注释
- 运行时
:编译器将注释记录在类文件中,并在运行时由VM保留,因此可以反射地读取注释
- 来源
:编译器将丢弃注释
文档()非常清楚。是的,我已经读过了,但实际上我不明白它是如何工作的。事实上,如果我尝试使用“this phrase”:“注释”将由编译器记录在类文件中,但不需要在运行时由VM保留。""“然后打开一个反编译类,我在其中放置了一个带有保留策略类的注释,但我什么也找不到……那么您的反编译器似乎不支持注释。jd gui工作正常。谢谢问题是我的反编译器dj和jad。。。给我看看!!是的,我也这么认为,但是在反编译类中什么都不存在!!!所以我很困惑。。。我将尝试使用javap工具检查类文件,javap不返回任何内容,然后放在哪里?RetentionPolicy.class的任何用例?感谢您的引用,这里最有趣的是RetentionPolicy.CLASS
的用例,你能解释一下为什么RetentionPolicy.CLASS是有趣的/令人惊讶的默认值吗?@sudocoder-参考以下链接:和。我相信字节码插装需要这个特殊的策略。尽管我自己从未使用过它。在本系列的下一篇文章的最后,我将展示Java的反射功能如何得到增强,以帮助您在运行时发现注释,以及注释处理工具“apt”如何让您在构建时使用注释。这篇文章在哪里?@Sushant:我不确定它在哪里:)。尽管不推荐使用apt
,但请参考此。对于使用反射发现注释,internet上有多个教程。你可以从查看java.lang.Class::getAnno*
和java.lang.reflect.Method
和java.lang.reflect.Field
中的类似方法开始。那么知道Runtime.SOURCE和Runtime.Class有什么用吗?@PraveenKamath我不知道它们在哪里有用。只有当您正在做大多数开发人员从未做过的低级JVM工作时,才可能发生这种情况。如果您找到了它们的应用程序,请告诉我。@PraveenKamath运行时。SOURCE
对于仅在编译时检查的内容很有用(例如@Override
)。