当@SuppressWarnings(“ deprecation”)不起作用时,如何避免弃用警告? [英] How to avoid deprecation warnings when @SuppressWarnings("deprecation") doesn't work?

查看:734
本文介绍了当@SuppressWarnings(“ deprecation”)不起作用时,如何避免弃用警告?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个Java项目。我们为 -Xlint (启用警告)和 -Werror (将警告作为错误处理)标志> javac ,以确保我们的代码没有警告。最近,我们决定弃用一门课程。问题是在某些情况下 @SuppressWarnings( deprecation)根本不会抑制过时警告,从而导致构建失败。以下是我遇到过的用例列表:

We have a Java project. We enable -Xlint (enable warnings) and -Werror (treat warning as error) flags for javac, to make sure our code is warning-free. Recently we decide to deprecate a class. The problem is in some cases @SuppressWarnings("deprecation") will not suppress the deprecation warning at all, resulting in build failure. Below is a list of use cases that I ran into:


  1. 已导入其他未弃用的类中。

  2. 已导入其他不推荐使用的类中。

  3. 父类。

  4. 类型参数。例如,

  1. Imported in other non-deprecated classes.
  2. Imported in other deprecated classes.
  3. Parent class.
  4. Type parameter. For example

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

但是,即使没有压制,也没有警告:

However, this one has no warning even without suppress:

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


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

AFAIK, there is no syntax for annotating imports, so for case 1 and 2 our solution is to either import * or avoid importing. For case 3 and 4, both Java 6 and 7 do not suppress the warning. Java 8 will correctly suppress it (maybe a bug is fixed). So far no solution for this.

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

Unfortunately, we have to support Java 6, 7 and 8 at this point. Is there way to deal with the problem? It is a road block for our Java API evolution.

附录

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

Many people ask why do we still use the deprecated class in our own codebase. The reason is that the project is a library, supporting many different clients. When introducing new replacement API, we have to first deprecate our old API, keep it in our codebase, wait for all clients to migrate then remove it. There are three common use cases:


  • 我们弃用了类 Foo Bar ,其中 Foo 扩展了 Bar 。这是我的问题中的情况2和3。

  • 我们弃用了类 Foo Bar ,其中 Foo 扩展了 Collection< Bar> 。第2种情况和第4种情况。

  • 我们必须保留类 Foo Bar 。测试代码将导入这些类。就是这种情况1。

  • We deprecate class Foo and Bar, where Foo extends Bar. This is the case 2 and 3 in my question.
  • We deprecate class Foo and Bar, where Foo extends Collection<Bar>. This is the case 2 and 4.
  • We must keep all test code for class Foo and Bar. The test code imports these classes. This is the case 1.

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

Why keep the test? Don't forget that if a serious bug (e.g. memory leak, security issue) is discovered, and the clients can't easily migrate to the new version, we still need to provide bug fix to the old API. And all changes must be tested.

我觉得我们的情况在软件库开发和API演变中应该很普遍。出乎意料的是,Java花了这么长时间(直到Java 8)才解决了该错误。

I feel our situation should be fairly common in software library development and API evolution. Surprisingly it took Java such long time (until Java 8) to fix the bug.

推荐答案

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

I'm sorry to say that I don't have a solution to the problem you're facing, though as you've observed, there has been some progress. We've been trying to get rid of all the Java compilation warnings in the JDK itself, and this has been a long, difficult process. During JDK 8 development in 2011 I helped kick off the warnings cleanup effort and I later co-presented a JavaOne talk (slides and audio) on the subject.

最近,我的同事Joe Darcy继续进行警告清理工作,并研究了不同的警告类别,并且最终达到了弃用警告。如您所述,编译器在处理抑制弃用警告方面存在一些错误,例如 JDK 8中已修复的JDK-6480588 。不幸的是,在JDK 8中仍然无法禁止有关已弃用物品进口的警告。 JDK-8032211 这个错误是最近在我们的JDK 9开发线中修复的。实际上,我们仍在调整 @Deprecated 注释的处理方式。例如,错误 JDK-6481080 阐明了尝试使用 package-info.java 文件中> @Deprecated 实际上并不弃用该软件包。该错误已于上周修复。还有尚待完成的工作,但它在某种程度上是推测性的

More recently, my colleage Joe Darcy has continued the warnings cleanup work and has worked through the different warnings categories and has finally reached deprecation warnings. As you noted, there have been some bugs in the compiler's handling of suppression of deprecation warnings, such as JDK-6480588 which was fixed in JDK 8. Unfortunately, it is still not possible in JDK 8 to suppress warnings on imports of deprecated items. This bug, JDK-8032211, was fixed quite recently in our JDK 9 development line. In fact, we're still tuning up the handling of the @Deprecated annotation. For example, bug JDK-6481080 clarifies that attempting to use @Deprecated in a package-info.java file does not in fact deprecate the package; this bug was fixed just last week. And there is more work to be done but it's somewhat speculative at this point.

JDK面临与您类似的问题,因为我们必须为仍在使用它们的客户端维护不推荐使用的API。但是,由于我们在内部使用和实现此类API,所以我们要抑制很多弃用警告。在撰写本文时,在我们的JDK 9开发线中,我们 still 在没有弃用警告的情况下仍无法编译系统。结果,用于棉绒警告的 javac 选项仍然是:

The JDK is facing similar problems to yours, in that we have to maintain deprecated APIs for clients that are still using them. But since we use and implement such APIs internally, we have a lot of deprecation warnings to suppress. As of this writing, in our JDK 9 development line, we still have not been able to compile the system without deprecation warnings. As a result, the javac options for lint warnings are still:

-Xlint:all,-deprecation

您可能还必须在编译中禁用弃用警告,特别是如果您仍在使用JDK 6的情况下,这时我还看不到解决方法。

You will probably have to disable deprecation warnings in your compilation as well, especially if you are still building on JDK 6. I don't see a way around it at this point.

关于您的一个弃用案例的最后一点:

One final note on one of your deprecation cases:

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

这不会发出弃用警告,也不应该发出。 Java语言规范,第9.6节.4.6 ,指定如果已弃用的实体在自身已弃用的实体内使用,则不发出弃用警告。

This does not issue a deprecation warning, nor should it. The Java Language Specification, section 9.6.4.6, specifies that deprecation warnings are not issued if the use of a deprecated entity is within an entity that is itself deprecated.

这篇关于当@SuppressWarnings(“ deprecation”)不起作用时,如何避免弃用警告?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆