Java 中的重构方法和二进制兼容性

发布于 2024-08-03 19:14:51 字数 724 浏览 7 评论 0原文

当重构方法时,很容易在 Java 中引入二进制不兼容(与以前版本的代码)。

考虑更改方法以将其参数类型扩展到父接口:

 void doSomething(String x);

 // change it to

 void doSomething(CharSequence c);

使用此方法的所有代码将继续编译而不进行更改,但它确实需要重新编译(因为旧的二进制文件将因 MethodNotFoundError 而失败)。

将一个方法拉到父类中怎么样?这需要重新编译吗?

// before
public class B extends A{
    protected void x(){};
}

// after
public class A {
    public void x(){};
}
public class B extends A{}

该方法已从 B 移至父 A。它还将可见性从 protected 更改为 public(但这不是问题)。

我是否需要在 B 中维护一个“二进制兼容性包装器”,或者它会继续工作(自动分派到父类)?

 // do I need this ?
 public class B extends A{
     // binary compatibility wrapper
     public void x(){ super.x(); }
 }

When refactoring methods it is easy to introduce binary incompabilities (with previous versions of the code) in Java.

Consider changing a method to widen the type of its parameter to a parent interface:

 void doSomething(String x);

 // change it to

 void doSomething(CharSequence c);

All the code that uses this method will continue to compile without changes, but it does require a re-compile (because the old binaries will fail with a MethodNotFoundError).

How about pulling a method up into a parent class. Will this require a re-compile?

// before
public class B extends A{
    protected void x(){};
}

// after
public class A {
    public void x(){};
}
public class B extends A{}

The method has been moved from B to the parent A. It has also changed visibility from protected to public (but that is not a problem).

Do I need to maintain a "binary compatibility wrapper" in B, or will it continue to work (automatically dispatch to the parent class)?

 // do I need this ?
 public class B extends A{
     // binary compatibility wrapper
     public void x(){ super.x(); }
 }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

帥小哥 2024-08-10 19:14:51

“加宽”会影响方法的签名,因此不兼容二进制。将方法移动到超类不会影响方法签名,因此它会起作用。 Eclipse 有一个很棒的文档,描述了 API 和 ABI 兼容性:

http://wiki.eclipse.org/Evolving_Java-based_APIs

第 2 部分中有更明确的规则:

http://wiki.eclipse.org/Evolving_Java-based_APIs_2

我相信您对“更改形式参数的类型”(即您所说的加宽)或“将 API 方法向上移动类型层次结构”(即您所说的拉入父级)感兴趣班级)。

"Widening" affects the signature of the method so that is not binary compatible. Moving a method to a superclass does not affect the method signature, so it will work. Eclipse has a great document that describes API and ABI compatibility:

http://wiki.eclipse.org/Evolving_Java-based_APIs

More explicit rules are in part 2:

http://wiki.eclipse.org/Evolving_Java-based_APIs_2

I believe you're interested in "Change type of a formal parameter" (i.e., what you refer to as widening) or "Move API method up type hierarchy" (i.e., what you refer to as pull into a parent class).

心欲静而疯不止 2024-08-10 19:14:51

它应该继续自动工作,因为 Java 具有动态链接

It should continue to work automatically as Java has dynamic linking

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文