当@SuppressWarnings(“deprecation”)不起作用时,如何避免弃用警告?

我们有一个Java项目。我们为 启用 (启用警告) 和 (将警告视为错误) 标志,以确保我们的代码没有警告。最近,我们决定弃用一个类。问题是在某些情况下根本不会禁止使用警告,从而导致构建失败。以下是我遇到的用例列表:-Xlint-Werrorjavac@SuppressWarnings("deprecation")

  1. 在其他未弃用的类中导入。
  2. 在其他已弃用的类中导入。
  3. 父类。
  4. 类型参数。例如

    @SuppressWarnings("deprecation")
    public class Foo extends Bar<DeprecatedClass>
    { ... }
    

    但是,即使没有抑制,这个也没有警告:

    @Deprecated
    public class DeprecatedClass extends Bar<DeprecatedClass>
    { ... }
    

AFAIK,没有用于注释导入的语法,因此对于情况1和2,我们的解决方案是导入*或避免导入。对于情况 3 和 4,Java 6 和 7 都不会禁止显示警告。Java 8将正确地抑制它(也许修复了一个错误)。到目前为止,还没有解决方案。

不幸的是,我们必须在这一点上支持Java 6,7和8。有没有办法解决这个问题?这是我们Java API发展的一个障碍。

补遗

许多人问为什么我们仍然在自己的代码库中使用已弃用的类。原因是该项目是一个库,支持许多不同的客户端。在引入新的替换 API 时,我们必须首先弃用旧 API,将其保留在代码库中,等待所有客户端迁移,然后将其删除。有三种常见的用例:

  • 我们弃用类 和 ,其中 extends .这就是我的问题中的情况2和3。FooBarFooBar
  • 我们弃用类 和 ,其中 extends .这是情况 2 和 4。FooBarFooCollection<Bar>
  • 我们必须保留类 和 的所有测试代码。测试代码导入这些类。情况如下 1.FooBar

为什么要保留测试?不要忘记,如果发现严重的错误(例如内存泄漏,安全问题),并且客户端无法轻松迁移到新版本,我们仍然需要为旧API提供错误修复。所有更改都必须经过测试。

我觉得我们的情况在软件库开发和API演进中应该相当普遍。令人惊讶的是,Java花了这么长时间(直到Java 8)来修复这个错误。


答案 1

我很抱歉地说,我没有解决你所面临的问题的方法,尽管正如你所观察到的,已经取得了一些进展。我们一直在努力摆脱JDK本身中的所有Java编译警告,这是一个漫长而艰难的过程。在 2011 年的 JDK 8 开发期间,我帮助启动了警告清理工作,后来我共同介绍了有关该主题的 JavaOne 演讲幻灯片和音频)。

最近,我的同事Joe Darcy继续了警告清理工作,并完成了不同的警告类别,并最终达到了弃用警告。如您所见,编译器在处理抑制弃用警告时存在一些错误,例如在 JDK 8 中修复的 JDK-6480588。遗憾的是,在 JDK 8 中仍然无法禁止显示有关已弃用项的导入的警告。这个 bug JDK-8032211 最近在我们的 JDK 9 开发系列中得到了修复。事实上,我们仍在调整注释的处理。例如,bug JDK-6481080 阐明了尝试在文件中使用实际上不会弃用该包。这个错误上周刚刚修复。还有更多的工作要做,但在这一点上,这有点投机。@Deprecated@Deprecatedpackage-info.java

JDK 面临着与您的问题类似的问题,因为我们必须为仍在使用它们的客户端维护已弃用的 API。但是,由于我们在内部使用和实现此类 API,因此需要禁止使用许多弃用警告。在撰写本文时,在我们的 JDK 9 开发系列中,我们仍然无法在没有弃用警告的情况下编译系统。因此,Lint 警告的选项仍然是:javac

-Xlint:all,-deprecation

您可能还必须在编译中禁用弃用警告,特别是如果您仍在 JDK 6 上进行构建。在这一点上,我看不到解决它的方法。

关于您的弃用案例之一的最后一点说明:

@Deprecated
public class DeprecatedClass extends Bar<DeprecatedClass> { ... }

这不会发出弃用警告,也不应该发出。Java 语言规范第 9.6.4.6 节指定,如果已弃用实体的使用位于本身已弃用的实体中,则不会发出弃用警告。


答案 2

考虑使用 -Xmaxwarns,您可以控制停止前的警告次数。

或者尝试收集警告的数量并使集成过程失败,而不是编译。

例如:https://issues.apache.org/jira/browse/HADOOP-11252。提交到hadoop项目的每个代码都需要通过自动化CI,并且它给出-1以增加警告数量。


推荐