Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 不同的保留策略如何影响我的批注?_Java_Annotations - Fatal编程技术网

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
)。