不同的保留策略如何影响我的注释?

问题描述 投票:151回答:5

任何人都可以清楚地解释java.lang.annotation.RetentionPolicy常数SOURCECLASSRUNTIME之间的实际差异吗?

我也不完全确定“保留注释”这个短语是什么意思。

java annotations
5个回答
192
投票
  • RetentionPolicy.SOURCE:在编译期间丢弃。编译完成后,这些注释没有任何意义,因此它们不会写入字节码。 示例:@Override@SuppressWarnings
  • RetentionPolicy.CLASS:在课堂加载期间丢弃。在进行字节码级后处理时很有用。有点令人惊讶的是,这是默认值。
  • RetentionPolicy.RUNTIME:不要丢弃。注释应该可以在运行时进行反射。示例:@Deprecated

来源:现在旧网址已经死了 hunter_meta 并用hunter-meta-2-098036取代。如果这种情况发生了变化,我会上传页面的图像。

Image(右键单击并选择'在新标签/窗口中打开图像')Screenshot of Oracle website


49
投票

根据你对类反编译的评论,我认为它应该如何工作:

  • RetentionPolicy.SOURCE:不会出现在反编译的类中
  • RetentionPolicy.CLASS:出现在反编译的类中,但在运行时不能用getAnnotations()反射检查
  • RetentionPolicy.RUNTIME:出现在反编译的类中,可以在运行时通过getAnnotations()的反射进行检查

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没有得到任何注释。

Examples on GitHub供你玩。


4
投票

RetentionPolicy.SOURCE:注释将在程序的源代码中提供,它既不在.class文件中,也不在运行时可用。由编译器使用。 RetentionPolicy.CLASS:注释将在.class文件中,但在运行时不可用。由字节代码操作工具(如ASM)使用来执行修改 RetentionPolicy.RUNTIME:注释可以在.class文件和运行时获得,通过getAnnotations()通过java反射进行检查。


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。

© www.soinside.com 2019 - 2024. All rights reserved.