【发布时间】:2017-04-19 10:44:20
【问题描述】:
我有一个公共 API,在多个项目中多次使用:
public interface Process<C extends ProcessExecutionContext> {
Future<?> performAsync(C context);
}
还有一个负责实现 Future 机制的抽象类(未显示)。我知道 all 项目子类化了相应的抽象类(其 performAsync 是 final),并且没有一个类在没有抽象实现者子类的情况下实现抽象接口。这是设计使然,因为这个“公共”API 在我们公司内部是“公共的”。
发现 Future 与 Spring 的 ListenableFuture 相比限制太大,我决定将接口扩展到
public interface Process<C extends ProcessExecutionContext> {
ListenableFuture<?> performAsync(C context);
}
我已经在示例中未显示的单个抽象超类中实现了 ListenableFuture。根据设计,不存在其他实现。
到目前为止,每个调用者都使用Future,它是ListenableFuture 的超级接口。如果你使用Future<?> future = processReturningListenable.performAsync(context),代码编译得很好。
问题是:如果我部署公共 API 的最新 JAR,其中包含 both 接口和抽象超类与 ListenableFuture 实现到现有环境,无需重新编译所有项目,performAsync 调用仍然有效吗?
即当接口被替换为返回原始类型的子类型的方法时,Java 是否授予接口的二进制兼容性?
我问这个是因为 1) 我发现没有人可以使用现有 JAR 文件进行简单测试,并且 2) 必须重新编译所有项目是一个红色警报。
我假设我的要求是可能的,因为 Java 方法名称由计算方法名称和输入参数的签名标识。更改输出参数不会更改方法的名称
【问题讨论】:
-
我不希望它在一个 jar 文件中产生任何影响 - 所以你应该能够只用一个小应用程序(一个接口,一个实现,一个调用者;重新编译接口+实现,但不是调用者,看看它是否仍然有效)。
-
@Jon Skeet:不需要测试;那样不行。
标签: java oop binary-compatibility jvm-bytecode