弃用覆盖方法

Deprecations On Overriding Method

我在 Eclipse 中发现了一些奇怪的东西 IDE。假设我有以下 类:

public class Super {
    @Deprecated
    public void doNotUseThisMethod() {
        // do magic
    }
}

public class Sub extends Super{
    @Override
    public void doNotUseThisMethod() {
        // why is this not deprecated?
    }
}

覆盖已弃用的方法肯定会导致警告(因为不使用它的原因相同)。仍然在 Eclipse Luna 和 Mars 的全新工作区中,上面的代码根本不会产生警告。而且我也找不到任何方法来启用它。

我发现 this bug 用于接口(我知道如果 Super 是一个接口,应该没有警告)这意味着曾经有一个警告。

所以发生了什么事?是否有任何理由覆盖已弃用的方法不应导致警告?我可以做些什么来再次启用此功能吗?

您需要在 类 的开头使用 @SuppressWarnings("deprecation") 来实现已弃用的 interface/function.

实际上这种行为对我来说似乎是正确的:当你覆盖一个方法是一个符号时,你为它实现了一个新代码。


为避免错误,如果您使用已弃用的超级方法,eclipse 将发出警告:

class Sub extends Super{
    @Override
    public void doNotUseThisMethod() { // <---------------*
        super.doNotUseThisMethod();   // deprecated! <----*
    }
}

但是,如果您在不使用已弃用的 super.method() 的情况下覆盖已弃用的方法功能,则 新方法未被定义弃用,因为您在实现它时未使用旧方法 .

public class Sub extends Super{
    @Override
    public void doNotUseThisMethod() {
        // new logic + not using super.method() = not a deprecated method!!
    }
}

如果不应该使用覆盖已弃用的那个,也必须注释为已弃用,如下所示:

public class Super {    
    @Deprecated
    public void doNotUseThisMethod() {
        // do magic
    }
}

public class Sub extends Super{
    @Override
    @Deprecated  // <---------------------------*
    public void doNotUseThisMethod() { //       |
        // this is deprecated also!!!! // <-----*
    }
}

SIDE注意:另一个问题是您的方法名称是否会引起混淆。


But doesn't @Deprecate also mean "we're going to delete this method soon", which will break the code of the subclass thanks to the @Override annotation? (That's exactly why I need the warning - to prevent other developers from overriding a method I'm going to delete. But as it is they won't even get a warning.) – Steffi S.

实际上开发人员可能会删除该方法,但弃用更多的是因为旧方法不使用代码,然后开发人员创建一个新的方法,使用新的名称并将弃用的方法保留为遗留。

但是...如果这个方法被删除会发生什么?

首先,这意味着 Java(或框架,或实用程序)版本的更改,这应该谨慎进行,不推荐使用的方法不会是您唯一的问题。

如果你选择大版本并且删除了一些不推荐使用的方法,你就不会有太大问题......为什么?您的 IDE 会清楚地将此方法标记为错误,您只需要删除 @Override 注释,让您的逻辑在您的覆盖方法中是安全的。

JLS 在这一点上非常清楚(因为它在大多数方面都是如此)。

A program element annotated @Deprecated is one that programmers are discouraged from using, typically because it is dangerous, or because a better alternative exists.

A Java compiler must produce a deprecation warning when a type, method, field, or constructor whose declaration is annotated with @Deprecated is used (overridden, invoked, or referenced by name) in a construct which is explicitly or implicitly declared, unless:

  • The use is within an entity that is itself annotated with the annotation @Deprecated; or

  • The use is within an entity that is annotated to suppress the warning with the annotation @SuppressWarnings("deprecation"); or

  • The use and declaration are both within the same outermost class.

(https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.6.4.6)

要完全符合 JLS,Eclipse 必须 用警告标记您的 doNotUseThisMethod()。似乎很久以前,它曾经这样做过,但是在 2003 年 bug 48335 出现了,并且该警告成为首选。如错误评论中所述,默认值为 "disabled"。 (默认值应该是 "enabled" 甚至远程兼容 JLS。请随时提交错误以更改它。)我没有进行详尽的搜索,但由于您看到的行为与此一致,我要大胆地说,这就是它从那以后一直保持的样子。

既然是偏好,你可以改变它。只需转到 "Window -> Preferences",然后 select "Java -> Compiler -> Errors/Warnings"。向下滚动到 "Deprecated and restricted API" 并选中 "Signal overriding or implementing deprecated method" 旁边的框。右侧稍上方有一个下拉菜单,您可以在其中选择 "Error"、"Warning" 或 "Ignore"。 Select你喜欢的那个。

该设置仅影响您的本地 IDE。

要让您的整个团队使用该设置,您需要设置项目特定设置。在同一个首选项屏幕上,右上角有一个 link 到 "Configure Project Specific Settings"。单击它,select 您要为其设置首选项的项目,并执行与上述相同的操作。这将在项目的“.settings”文件夹中创建一个名为 "org.eclipse.jdt.core.prefs" 的文件。 (您无法在 Package Explorer 中看到它们。您需要在 Navigator 视图中查看它们。)创建后,您可以将它们添加到您的源代码管理中,它们将应用于您团队中从事该工作的每个人项目。

是的,每个项目都必须这样做。