【问题标题】:Does removing an interface break code calling methods on the object?删除接口会破坏对象上的代码调用方法吗?
【发布时间】:2009-12-11 07:52:04
【问题描述】:

我需要在 Java 中进行一些重构,并且需要保持一定程度的二进制兼容性。在这种情况下,我想删除一些旧接口,它们不再在任何地方使用,并且需要相当大的(并且不推荐使用的)外部依赖项。

我有实现接口I 的类C,并且我有调用C 实例上的方法(在接口中声明)的代码。调用代码知道它正在使用C,而不仅仅是接口。

 class C implements I {
      void theMethod(){} ; // is declared in the interface I
 }

 C object;
 object.theMethod();

当我从类定义中删除接口(但保留所有方法)时,调用代码(根本不引用接口)是否仍然有效(无需重新编译)?

【问题讨论】:

  • 尝试比编写和格式化这个问题花费更少的时间;)
  • 完成,请参阅我的答案中的链接,了解您可能感兴趣的情况

标签: java refactoring binary-compatibility


【解决方案1】:

是的,它会起作用 - 只要它没有在任何地方明确引用接口I

来自JLS: Resolution of Symbolic References

类的二进制表示 或接口引用其他类 和接口及其领域, 方法和构造函数 象征性地,使用二进制名称 (§13.1)的其他类和 接口

引用类C的字段/方法的类ClientClass不包含对该类可能实现的接口I的隐式引用。

【讨论】:

  • 这是否意味着我什至可以删除抽象基类并将方法放入现在没有父级的子类中?
  • 是的,同样的规则适用。基类甚至不必是抽象的 - 只要您将整个层次结构“展平”为子类 AND 基类从未从客户端代码中显式引用,您就可以了。
  • 这是关于方法/构造函数声明的 JLS 部分:java.sun.com/docs/books/jls/third_edition/html/…
【解决方案2】:

只要C 类的对象从未被称为I,它就可以工作。

您也可以参考Evolving Java-based APIs part 2

【讨论】:

    【解决方案3】:

    如果调用代码在任何地方导入接口,您可能会遇到问题。如果在任何调用代码中都没有接口的import,那么您可以有理由相信您的重构将按计划进行。

    【讨论】:

    • 是的,唯一使用相关接口的地方是(或者现在应该......)类声明。
    猜你喜欢
    • 1970-01-01
    • 2023-03-03
    • 2018-09-15
    • 2018-12-20
    • 2021-11-05
    • 1970-01-01
    • 1970-01-01
    • 2021-01-12
    • 1970-01-01
    相关资源
    最近更新 更多