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

时间:2018-05-12 04:36:53

标签: java deprecated suppress-warnings deprecation-warning

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

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

似乎API开发人员的最佳意图最终会创建更多与实现的业务逻辑无关的代码 - 如果API已被弃用但是在关联的警告被抑制的情况下不断使用它似乎会降低代码的性能在最糟糕的恕我直言中替换弃用的库时,充其量和潜在的应用程序突破点。

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

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

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

参考文献:

3 个答案:

答案 0 :(得分:4)

步骤1:宣布删除

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

  
      
  • API很危险(例如,Thread.stop方法)。

  •   
  • 有一个简单的重命名(例如,AWT Component.show/hide替换为setVisible)。

  •   
  • 可以使用更新,更好的API。

  •   
  • 将删除已弃用的API。

  •   

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

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

Java 8或更低版本

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

Java 9或以上

从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启用)并且{em>未被@SuppressWarnings("deprecation")抑制。相反,人们必须使用新的@SuppressWarnings("removal")来抑制它,这可能会让开发人员在没有充分理由的情况下三思而后行。

此外,您可以使用

显式声明引入弃用的库版本
@Deprecated(since="<version>")

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

步骤2a:运行时警告

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

步骤2b:静态代码分析

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

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

第3步:删除API

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

答案 1 :(得分:2)

已弃用的API仅在使用@Deprecated注释时才有用。如果API客户端在被标记为已弃用多年之后仍能成功使用它,那么说API提供商无法以任何实际方式帮助他们是正确的。

  

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

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

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

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

答案 2 :(得分:2)

  

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

从谁的角度看实用?

从经常忽略/禁止弃用警告的开发人员的角度来看,他们已经拥有了他们的解决方案&#34; ......这是无视问题的。但另一方面,其他人无法阻止他们这样做。但另一方面的另一面是......最终......不是其他人......业务。

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

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

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

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

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

  • 提供了更具信息性的弃用标记,
  • 提供了一个工具(jdeprscan),用于扫描针对Java SE API的弃用违规行为。