Java - 抽象类和抽象类的二进制兼容性子类

发布于 2024-09-01 18:58:23 字数 189 浏览 0 评论 0原文

在Java中,我定义了一个抽象类,其中包含具体方法和抽象方法,并且必须由第三方开发人员独立地对其进行子类化。只是为了确定:我可以对抽象类进行任何与它们的类源兼容但不二进制兼容的更改吗?换句话说:在他们编译了子类之后,我可以更改抽象类吗?除了向其中添加抽象方法或从中删除子类调用的受保护方法之外,这当然是源不兼容的——在某种程度上这可能会迫使他们重新编译他们的子类?

In Java, I define an abstract class with both concrete and abstract methods in it, and it has to be subclassed independently by third-party developers. Just to be sure: are there any changes I could make to the abstract class that are source compatible with their classes but not binary compatible? In other words: after they have compiled their subclasses, could I change the abstract class - apart from e.g. adding an abstract method to it or removing a protected method from it that is called by subclasses, which are of course source incompatible - in a way that could force them to recompile their subclasses?

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

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

发布评论

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

评论(3

生活了然无味 2024-09-08 18:58:23

如果现在改变你的系统还不算太晚,我建议你这样做。覆盖通常不是自定义功能的好方法,因为它非常脆弱。例如,如果您稍后使用客户已使用的方法名称(它们现在无意中自动覆盖),那么覆盖可能会完全破坏您的类的不变量。通常提供定制的更好方法是为您的客户提供一个仅限于定制行为的接口,然后您拥有一个依赖于该接口实例的完全具体的类,并在需要时适当地委托给该接口使用定制的行为。这样,你的代码和客户端的代码是完全分开的,并且不会互相干扰。

If it isn't too late to change your system, I would suggest that you do that. Overriding is usually not a good way to customize functionality, as it is incredibly fragile. For example, if you later use a method name that your clients have used (which they are now unintentionally automatically overriding), then it is possible that the override will completely break the invariants of your class. A usually better way of providing customization is to give your clients an interface which is limited to just the customized behavior, and then you have a fully concrete class that depends on an instance of this interface, and delegates appropriately to the interface when it needs to use the customized behaviors. This way, your code and your client's code are completely separated, and they won't interfere with each other.

愛放△進行李 2024-09-08 18:58:23

我假设您在技术意义上使用“二进制不兼容”;例如,类加载器检测到不兼容并拒绝加载类。

如果您添加了一个可见方法将其声明为final,并且该方法与第三方子类中某些现有方法的签名发生冲突,也可能会引入二进制不兼容性。但是,如果该方法是非最终方法,则现有方法将变成对(新)方法的覆盖,这可能会导致问题......但不会导致二进制不兼容。

同样,添加新的可见字段将导致隐藏,可能导致行为混乱,并且会破坏对象序列化。但这不会导致二进制不兼容。

一般来说,这表明您需要考虑应用程序语义问题以及简单的二进制兼容性问题。 Java 类型系统在这方面无法为您提供帮助。

为了完整起见,您可以在代码中执行其他一些操作,这会破坏第 3 方类

  • 的二进制兼容性:降低抽象类和/或其方法的可见性,
  • 更改用作参数结果的其他类的签名,以及异常类型,
  • 更改抽象类扩展的超类链,或者在这些类中进行不兼容的更改,或者
  • 更改抽象类实现的接口树,或者在这些接口中进行不兼容的更改。

I am assuming that you are using "binary incompatibility" in the technical sense; e.g. where the classloader detects the incompatibility and refuses to load the classes.

Binary incompatibility could also be introduced if you added a visible method and declared it final, and that method collided with the signature of some existing method in a third-party subclass. However, if the method is non-final, the existing method will turn into an override of your (new) method which might cause problems ... but not binary incompatibility.

Likewise, adding new visible fields will result in hiding, may result in confusing behavior and will break object serialization. But this will not result in binary incompatibility.

In general this points to the fact that you need to consider application semantic issues as well as simple binary compatibility. And the Java type system won't help you there.

For completeness, there are a other things that you could do in your code that would break binary compatibility for the 3rd party classes:

  • reduce the visibility of your abstract class and/or its methods,
  • change the signatures of other classes used as parameter result and exception types,
  • change the chain of superclasses that your abstract class extends, or make an incompatible change in those classes, or
  • change the tree of interfaces that your abstract class implements, or make an incompatible change in those interfaces.
小姐丶请自重 2024-09-08 18:58:23

当然。

您可能会意外地使用他们使用过的方法名称,该方法名称现在突然被覆盖,可能会产生截然不同的结果。

您可以向类添加字段,这会扰乱序列化等。

Sure.

You can accidently use a method name that they've used, which is now suddenly overridden, with perhaps dramatically different results.

You can add fields to the class which mess up serialization etc.

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