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

时间:2010-05-14 22:07:54

标签: java binary-compatibility

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

3 个答案:

答案 0 :(得分:9)

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

答案 1 :(得分:5)

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

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

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

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

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

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

答案 2 :(得分:2)

不确定

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

您可以在类中添加字段,这会破坏序列化等。

相关问题