【问题标题】:Java: How to avoid deprecated warning in derived interfaces which override deprecated members?Java:如何避免在覆盖弃用成员的派生接口中出现弃用警告?
【发布时间】:2009-07-31 15:55:31
【问题描述】:

考虑以下简化的接口继承层次结构:

// Starting point:
public interface Base {
    void Foo();
}

public interface Derived extends Base {
}

打算将Foo方法从Base接口移动到Derived接口:

// Desired end-point:
public interface Base {
}

public interface Derived extends Base {
    void Foo();
}

为了逐步实现这一重大更改,希望在一段时间内保持Base 接口的向后兼容性。

这可以通过将Base接口上的方法标记为@Deprecated来实现:

// Intermediate state:
public interface Base {
    /**
     * @deprecated This method is deprecated as of release X. Derived.Foo should be used instead.
     */
    @Deprecated void Foo();
}

public interface Derived extends Base {
    void Foo(); 
}

当我编译这段代码时,我收到了 Derived 的编译器警告:

[deprecation] 接口 Base 中的 Foo() 已被弃用

奇怪的是,如果我从Base 的文档中删除@deprecated(但保留@Deprecated),此警告就会消失。

我收到此警告是否正确,如果是,我该如何解决?


警告似乎表明Derived.Foo 正在“使用”Base.Foo(已弃用)。但是,Derived.Foo 唯一能够“使用”已弃用的Base.Foo 的能力是覆盖它。这似乎是说您不允许在派生方法中覆盖已弃用的接口方法。

如果是这种情况,我应该用@SuppressWarnings("deprecation") 装饰Derived 以抑制警告吗?

【问题讨论】:

  • 您使用的是哪个版本的 Java?我似乎记得这在某些时候被认为是一个错误,可能已修复......但我不能确定我是否正确地记住了这一点。我明白你的意思了。

标签: java interface overriding deprecated


【解决方案1】:

我相信您的要求是有效的,我毫不怀疑覆盖已弃用的方法是正确的方法。

我相信@deprecated 和@Deprecated 之间的区别主要是历史性的。 @Deprecated 是 java 5 中的官方方式,但它是新的,所以我们希望用 @deprecated 将它加倍。

还请注意,可悲的是,@Deprecated 不允许您指定信息 .. 虽然通常需要信息,例如说明应该使用什么作为替代品,或者预计何时完全删除不推荐使用的方法.

不知道更多,并且知道一旦您有效删除超级方法,问题就会消失,我会使用@SuppressWarnings("deprecation"),可能带有评论让您的继任者理解......(以及另一个评论超级方法,告诉他们在删除方法时删除所有内容)。 ;-)

【讨论】:

    【解决方案2】:

    如果我理解正确,您需要在实现已弃用接口/功能的类的开头使用 @SuppressWarnings("deprecation") 。还是我离基地太远了?

    【讨论】:

    • 这听起来很合理,但是这里的问题是没有实现类。就这两个接口。该警告似乎表明Derived.Foo 正在“使用”Base.Foo(已弃用)。但是Derived.Foo 的唯一能力是“使用”已弃用的Base.Foo 是覆盖它。这似乎是说您不允许在派生方法中覆盖已弃用的接口方法。这合理吗?
    • 我不知道“不允许”,但是由于您实际上是在覆盖已弃用的函数,因此在我看来它会抱怨它是合理的。有什么方法可以将它们解耦并使它们成为两个完全独立的接口,还是 Derived 必须扩展其他功能?
    【解决方案3】:

    如果您将 @Deprecated 添加到您的 Foo() 派生声明中,我相信警告会消失。

    public interface Derived extends Base {
        @Deprecated void Foo(); 
    }
    

    【讨论】:

    • 一个奇怪的提示是,如果其他方法依赖于不推荐使用的方法,您可能会遇到一些难以推理的情况,例如 setVisible 依赖于我系统上的显示/隐藏,所以如果我创建一个类 JFrameEx 并覆盖弃用显示/隐藏并实现我自己的,然后我必须决定是否需要调用已弃用的超级显示/隐藏,如果这些方法已从超类中删除,你是否使用反射?跨度>
    【解决方案4】:

    没有办法实现你想要的。

    弃用是一种相对简单的机制,不支持这种用例。

    弃用的工作方式是任何引用已弃用的方法或字段的内容都会生成警告。

    唯一的例外是使用已弃用的方法/字段的代码本身已弃用。

    【讨论】:

    • 这是正确的反应(而不是抑制警告),因为您在派生方法中依赖已弃用的 API。
    • Derived 上引入方法的目的是将方法从Base 迁移到Derived,因此我想弃用Base 上的方法并提供说明“使用这个方法在Derived"上。在这种情况下,我不赞成在 Derived 上弃用(新添加的)方法。
    • 这就是为什么我说“不支持这个用例”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-11
    • 1970-01-01
    相关资源
    最近更新 更多