什么';java.lang.annotation.Retention的原因是什么?

什么';java.lang.annotation.Retention的原因是什么?,java,annotations,retention,Java,Annotations,Retention,我很清楚保留政策的含义,知道他们做什么以及何时执行。对于我自己的注释,我确切地知道它们是在运行时、类文件中还是仅仅用于编译。然而,对于库中定义的任何注释,您永远无法确定 例如,javax.annotation.Generated用于标记生成的代码,但很少有用。由于处理字节码的工具比处理源代码的工具多得多,因此信息在使用之前就消失了 作为运行时缺少的注释ClassNotFoundException(与缺少接口不同),使用RetentionPolicy.runtime似乎不会造成任何伤害。还是我错了

我很清楚
保留政策的含义
,知道他们做什么以及何时执行。对于我自己的注释,我确切地知道它们是在运行时、类文件中还是仅仅用于编译。然而,对于库中定义的任何注释,您永远无法确定

例如,
javax.annotation.Generated
用于标记生成的代码,但很少有用。由于处理字节码的工具比处理源代码的工具多得多,因此信息在使用之前就消失了

作为运行时缺少的注释
ClassNotFoundException
(与缺少接口不同),使用
RetentionPolicy.runtime
似乎不会造成任何伤害。还是我错了


还是说节省几个字节是使用不同的
保留时间的原因?对我来说,这似乎造成了太多的问题,不值得这么做。我缺少什么?

注释的主要目的是为编译单元携带元数据。大多数标准注释都清楚地表达了有助于代码开发和编译的元信息(通过指定可由IDE或编译器验证的属性)

注释不是为修改语言的运行时语义而设计的。因此,注释在运行时是否可用本身不会改变执行。(当然,如果您主动使用元信息来调整您的实现行为,那么一切都是可能的。)

如果在库jar中的某个地方,注释被标记为
RetentionPolicy.RUNTIME
显然,从运行时访问注释(使用反射)对以后的用户很有用。
如果同时注释的实现来自另一个库,那么这种期望要么是没有保证的,要么是由于该注释的特定目的,可能只对某些用例有用。(当然,仅仅为不同的保留设置构建不同的jar版本是不合适的。)

因此,如果开发人员将注释标记为
RetentionPolicy.RUNTIME
,那么在期望运行时访问的地方,有一个明确的用例。注释实现是否使用相同的jar或不同的jar可能独立于用例(例如,基于其他结构化标准)。在任何情况下,如果您打算从这个用例中获益,那么在您的类路径中就会有这个注释库(因为您可能还需要其他组件),一切都很好。如果您不应用于此用例,那么您将不会受到缺少注释实现的影响

改写你的问题:


使用
运行时
保留不会对程序造成任何伤害,除了用死信息扰乱(字节码)可执行文件之外。只有当元信息的运行时使用是预期的(并且被认为是有用的)时,才使用
RUNTIME
保留增加了代码质量(在可维护性和可理解性方面)。

Java注释的灵感出现在2002年之前,大约是从Java 1.3过渡到Java 1.4的时候。当时的高规格桌面是2.5GHz左右的奔腾4或2GHz左右的Athlon XP+,RAM为256或512MB。如复习

问题是如何存储和检索有关代码的元数据。典型的解决方案是使用未进行类型检查或未直接链接到源代码的XML文件。其他人已经非正式地为代码生成工具扩展了JavaDoc(源代码和扩展API出现在JDK中)。解决方案Annotations是一个扩展Javadoc和JLS类规范的hack(非常好的hack)

很明显,最初的作者担心性能(在2002年,Java仍然相对缓慢,反射速度非常慢,Java运行时占用了大量内存;有些事情永远不会改变)。这是从介绍到:

因为许多注释将仅由开发工具使用,例如 在存根生成器中,一次保留所有注释没有什么意义 运行时间;这样做可能会增加运行时内存占用和危害 演出但是,有些注释类型很有用 在运行时,以及一些在只有访问权限的工具中有用的 对文件(不是源文件)进行分类。因此,某些注释是必需的 由编译器以类文件属性(JVM 4.7)和一些 然后在运行时检查这些注释中的任何一个 通过新的反射API

他们解决问题的方法是将问题分为三个用例:

VI.阅读注释

注释使用者可分为三组:

a。“内省程序”-查询运行时可见注释的程序 他们自己的程序元素。这些程序将加载两个带注释的 类和注释接口连接到虚拟机。(由 运行时可见,我们指的是保留 策略正在运行。)

b。“特定工具”-查询已知信息的程序 任意外部程序的注释类型。短线发生器,用于 例如,属于这一类。这些程序将读取注释 类而不将其加载到虚拟机中,但将加载 注释接口

c。“通用工具”-用于查询 任意外部程序的任意注释(例如 编译器、文档生成器和类浏览器)。这些 程序既不会加载注释类,也不会加载注释接口 进入虚拟机。这类项目据说是在“正常运作” 长度。”

这使得(当时)上述定义的“特定工具”和“通用工具”的重要用例能够在不给用户造成负担的情况下完成它们的工作