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

thS*_*oft 6 java binary-compatibility

在Java中,我定义了一个抽象类,其中包含具体和抽象方法,并且必须由第三方开发人员独立创建子类.只是为了确定:我是否可以对抽象类进行任何更改,这些更改与源类兼容,但不兼容二进制?换句话说:他们已经编制了各自的子类后,我能变抽象类 - 除了如增加一个抽象方法给它或移除它受保护的方法由子类,这是当然的源不兼容称为 - 的方式这可能会迫使他们重新编译他们的子类?

Mic*_*yan 9

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


Ste*_*n C 5

我假设你在技术意义上使用"二元不兼容"; 例如,类加载器检测到不兼容性并拒绝加载类.

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

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

一般来说,这表明您需要考虑应用程序语义问题以及简单的二进制兼容性.Java类型系统对你没有帮助.

为了完整起见,您可以在代码中执行其他操作,以破坏第三方类的二进制兼容性:

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