deprecated
我偶尔会遇到一种情况,我需要引入新的API或构造以供其他人试用,但是我知道在使用某些API后,它可能会根据其他人的反馈而改变。 在这种情况下,我想以某种方式注释该构造,以警告其他开发人员此新添加的构造的暂定性。 在这些情况下,我考虑了几种选择。
- 使用第三方注释,例如Guava的@Beta注释。
- 开发自定义注释。
- 仅使用注释/ Javadoc。
- 将@Deprecated注释与Javadoc @deprecated标记一起使用。
第三方注释
Guava的@Beta
注释的Javadoc文档指出:
表示在将来的发行版中,公共API(公共类,方法或字段)可能会发生不兼容的更改,甚至被删除。 带有此注释的API不受其包含库所作的任何兼容性保证。 请注意,此批注的存在并不表示所讨论的API的质量或性能,仅表示它不是“冻结的” API。
对@Beta
用法的这种解释似乎意味着这非常适合于可能被删除的“新”结构。 我在博客文章“ 两个普遍有用的番石榴注释 ”中讨论了更多有关此注释的内容。
使用第三方库的批注时的其他注意事项是,第三方库必须包含在一个人的类路径中,并且在最流行的Java IDE中通常不提供现成的支持以表示对该结构的特殊处理带有注释的注释。
自定义注释
如果由于其他任何原因未将库与批注一起使用,则在编写自己的自定义批注相对简单时,仅为批注添加新的库依赖项似乎有点繁重。 之前,我已经写过有关编写自定义@Unfinished批注的文章,该帖子讨论了如何在NetBeans 8.0.2和IntelliJ IDEA 14.0.3中为该自定义批注创建相应的自定义IDE检查。
以下代码清单提供了一个可用于此目的的自定义注释的示例。
@预览注释
package dustin.examples.annotations;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Preview
{/*** Anticipated release in which Preview status will no longer apply.** @return Anticipated release of feature*/String transition() default "";/*** Version in which this preview feature was introduced.** @return Release in which this preview feature was introduced.*/String since() default "";/*** Reasons this construct is considered "preview."** @return Reasons this construct is considered preview.*/String[] reasons() default {};
}
自定义注释在流行的Java IDE中缺少任何现成的支持。
仅评论
不一定需要使用批注,简单的注释(Javadoc或其他方式)可以解释特定的构造是初步的,可能会消失。 但是,就沟通意图而言,注释在许多方面都比注释弱。 使用IDE或其他工具解析注释比处理注释要困难得多。
@Deprecated批注和@deprecated Javadoc标记
可以使用@Deprecated
来使用标准注释来注释不赞成使用的构造,IDE,工具和脚本可以轻松地对其进行处理。 不幸的是, @Deprecated
注释从未得到我希望得到的全部支持,因为我希望它能更明确地说明为什么在决定让JDK 9增强@Deprecated变得不那么雄心勃勃时为什么不赞成使用某些东西。 Javadoc @deprecated
标记可用于记录该弃用实际上是针对可能会消失但也可能不会消失的“新”构造的。 如果决定保留“预览”结构,则可以删除@Deprecated
批注和@deprecated
Javadoc标记。
尽管@Deprecated
批注和@deprecated
Javadoc标记从包括内置IDE支持和大多数Java开发人员意识的标准中受益,但是使用它们标记可能会消失的新结构仍然有些不合适。可能会停留在周围。 文档“ 如何以及何时不推荐使用API ”的“ 何时不推荐使用 ”部分指出:“在设计API时,请仔细考虑它是否会取代旧的API。” 它进一步列出了弃用的三个原因,即“不安全,有错误或效率低下”,“在将来的版本中消失”和“鼓励不良的编码习惯”。
我并不是唯一认为“过时”标记可能会被删除或不应使用的内容的人。 NicolasFränkel概述了Java中的功能生命周期,并解释说Java中的弃用是“对每个人的大胆而明确的声明,至少在当前形式下,功能版本没有未来。”
Alex Buckley在jdk-dev邮件列表消息“ JEP 12:处理支持预览功能的标准API ”中写道:
我们想使用“弃用弃用”作为标记“此API与预览功能紧密相连”的方式。 如果预览功能成为永久功能,则将删除弃用项。 从终端弃用到没有弃用的转变是新颖的,但并不疯狂—弃用具有多种含义,并且其在JDK中的历史用法对于任何事情都不是很好的指导。
Buckley还引用了JEP 277 (“增强的弃用”)中有关弃用机制的使用的一段内容(我强调了Buckley强调的相同部分):
弃用是一种用于传达有关API生命周期的信息的技术:鼓励应用程序从API迁移过来,阻止应用程序形成对API的新依赖关系,并告知开发人员继续依赖API的风险 。
JDK 9引入的 “增强型” @Deprecated
注释可以通过其新添加的“ since ”和“ forRemoval ”元素在这种情况下有所帮助(Buckley称之为“出生时弃用弃用”)。 指定@Deprecated
注释的forRemoval()
为false
,并指定其since
为同一版本的Javadoc @since标记可以帮助开发者看到,构造从一开始弃用目前尚无计划将其删除。 为了使这种方法最有效,可能会写成将forRemoval
明确声明为false,而不是依赖于其隐式默认值。
可能我们的Java开发人员将需要开始考虑@Deprecated
和@deprecated
与过去有所不同。 尽管@Deprecated
批注和@deprecated
Javadoc标记仍“通知”我们对已注释/描述的结构的“持续依赖的风险”,但认为这样的结构将来必定会消失是不正确的。 如果我们习惯了已弃用的JDK构造中的这种替代含义,那么我们将更有可能考虑将相同的方法与我们自己新近添加但仍具有试验性的功能一起使用。
翻译自: https://www.javacodegeeks.com/2018/03/forward-looking-with-javas-deprecated.html
deprecated