Java弃用的API和SuppressWarnings“弃用” - 实用的方法

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

我见过许多using the Deprecated annotation on APIs的例子,以便将它们标记为“需要尽快更换”。

但是,在几乎所有这些情况下,代码开发人员不仅继续使用已弃用的API,还使用suppressed the deprecation warning

似乎API开发人员的最佳意图最终创建了与实现的业务逻辑无关的更多代码 - 如果API被弃用但是在关联的警告被抑制的情况下不断使用它似乎最好是代码的降级和在最坏的恕我直言中更换已弃用的库时潜在的应用程序断点。

这个问题有实际的解决方案吗?至少,如果它确实在CR中停留了相当长的时间,那么将这种情况标记为代码气味的方法是什么?

请建议您可能正在使用的实际解决方案(库,SCA,CR插件等......)

是否有任何计划的JRE / JDK功能可能有助于解决这种情况?我的研究目前还没有找到。

参考文献:

java deprecated suppress-warnings deprecation-warning
3个回答
5
投票

Step 1: Announce the removal

有人可能认为弃用API意味着宣布它将被删除,但这不是唯一的用例(如Java 7Java 9的相关文章中所述):

  • API很危险(例如,Thread.stop方法)。
  • 有一个简单的重命名(例如,AWT Component.show/hidesetVisible取代)。
  • 可以使用更新,更好的API。
  • 已弃用的API将被删除。

为了进一步复杂化,在Java 9之前,JDK中没有任何已弃用的API被删除(请参阅20 Years Of Java Deprecation),因此如果开发人员不认真对待弃用,那么这是可以理解的 - 无论是在JDK还是在其他地方。

因此,您需要清楚地沟通API真的,真的会被删除。执行此操作的方法取决于您的API编译的Java版本。

Java 8 or lower

在这些Java版本中,没有正式的方法可以明确区分各种弃用用例。您可以做的最好的事情是添加Javadoc标记@deprecated,不仅给出了弃用和列出备选方案的原因,还明确宣布了删除API的意图。

Java 9 or above

从Java 9开始,使用Enhanced Deprecation,您现在可以编写

@Deprecated(forRemoval=<boolean>)

明确记录你的意图。我认为,与Javadoc @deprecated(应该详细说明弃用的原因和列表备选方案)一起,这个标准化的标志是一个公平的警告。

将此标志设置为true,编译器将警告每次使用不推荐使用的元素,如下所示:

YourClass.java:<line>: warning: [removal] <method> in <class> has been
deprecated and marked for removal

默认情况下启用此警告(而不是必须使用-Xlint:deprecation启用),并且不会使用@SuppressWarnings("deprecation")抑制此警告。相反,人们不得不用新的@SuppressWarnings("removal")压制它,这可能会让开发人员在没有充分理由的情况下三思而后行。

此外,您可以显式声明引入了弃用的库版本

@Deprecated(since="<version>")

在Javadoc或源代码中看到这一点可以帮助开发人员评估更新代码的紧急程度。

Step 2a: Runtime warning

如果情况可行,请添加运行时提醒:当使用不推荐使用的API时,让它向控制台或日志文件(使用您使用的任何日志记录机制)发出警告,宣布这将不再适用于下一个主要版本。为避免垃圾邮件,您只能记录一次(例如private static boolean warningLogged)。

Step 2b: Static code analysis

可以设置像SonarQube(也可用作hosted service)的静态代码分析器来标记这些警告中的每一个。如果编译器的弃用使用警告被抑制,SonarQube规则"deprecated code should not be used"甚至可以工作。

SonarQube还会跟踪何时引入某个问题(即违反规则)(基于版本控制),并且您可以根据该日期以交互方式过滤其问题列表。例如,您可以列出代码库中已弃用代码的所有用法超过一年,以便您可以优先处理修复它们的工作。

Step 3: Remove the API

实际上,删除API不会给您的API用户留下他们不需要费心更改代码的印象。


2
投票

只要使用@Deprecated注释,弃用的API就没有用处。如果API客户端在被标记为已弃用多年之后仍然可以成功使用它,那么说API提供商没有以任何实际方式帮助它们是正确的。

这个问题有实际的解决方案吗?

是:让弃用意味着弃用,在宽限期之后,如果删除是正确的处理方式,则使弃用的API不可用。例如,如果您弃用具有安全风险的API,而不是在将来的版本中删除它会使弃用无用,并且可以看作是导致问题的原因。

@Deprecated注释只不过是文档,即使你注意到,其他开发人员也可以忽略它。

Java 9+的弃用可能更具信息性,但最终的决定仍然取决于使用API​​的开发人员,而这并不能解决问题。


2
投票

这个问题有实际的解决方案吗?

从谁的角度实用?

从经常忽略/抑制弃用警告的开发人员的角度来看,他们已经有了“解决方案”......这就是忽略这个问题。但另一方面,其他人无法阻止他们这样做。但另一方面是......最终......这不是其他人的事。

从希望弃用他们维护的API的开发人员的角度来看,他们已经有了解决方案。去做就对了。然后通过实际删除已弃用的API继续执行下一步。另一方面,它会惹恼一些人,其他人也会被烧毁。 (特别是那些经常忽略/抑制弃用警告的人。但请看上面:这是他们的问题。)

从关心/责任的角度来看,维护组织代码库的代码质量/完整性,是的,存在问题。但解决方案相对紧张:

  • 禁止使用@suppress代码(“弃用”)`。
  • 禁止构建脚本以关闭弃用警告。
  • 通过“grepping”源代码,在via SCI服务器插件,自定义样式检查器规则或(如果你想要粗略)中强制执行上述操作。
  • 对一个重复犯罪的程序员采取(隐喻)大棒。

是否有任何计划的JRE / JDK功能可能有助于解决这种情况?

如上所述,Java 9+增强了注释支持(请参阅JEP 277):

  • 提供更多信息性的弃用标记,以及
  • 提供了一个工具(jdeprscan),用于扫描针对Java SE API的弃用违规。
© www.soinside.com 2019 - 2024. All rights reserved.