简体   繁体   English

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

[英]Java - binary compatibility of abstract class & subclasses

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. 在Java中,我定义了一个抽象类,其中包含具体和抽象方法,并且必须由第三方开发人员独立创建子类。 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 eg 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? 换句话说:在编译了它们的子类之后,我可以更改抽象类 - 除了例如向它添加一个抽象方法或从子类中调用受保护的方法,这些方法当然是源不兼容的 - 在某种程度上这可能会迫使他们重新编译他们的子类?

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. 这样,您的代码和客户端的代码完全分开,并且它们不会相互干扰。

I am assuming that you are using "binary incompatibility" in the technical sense; 我假设你在技术意义上使用“二元不兼容”; eg 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. 如果添加了可见方法并将其声明为final ,并且该方法与第三方子类中某些现有方法的签名冲突,也可能会引入二进制不兼容性。 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. 但是,如果该方法是非final的,则现有方法将变为您的(新)方法的覆盖,这可能会导致问题......但不会导致二进制不兼容。

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. Java类型系统对你没有帮助。

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. 更改抽象类实现的接口树,或在这些接口中进行不兼容的更改。

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. 你可以在类中添加字段,这会搞乱序列化等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM