源兼容性是否总是意味着二进制兼容性?

Bal*_*nat 1 java

假设我编译我的类并lib_v1.0.jar分发我的二进制文件。然后我更新到lib_v1.1.jar. 假设我的源代码针对 v1.1 进行编译而没有错误,那么我的旧分布式二进制文件是否始终可以使用lib_v1.1.jar,或者我是否必须重新编译和重新分发新的二进制文件?

我阅读了https://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html,但找不到我的问题的明确或明确的答案。

Vik*_*tor 5

源兼容性并不意味着二进制兼容性。

例如,我们在库中有以下接口:

// jar v1.0 
interface Service {
   int calculate(); // signature: ()I
}
Run Code Online (Sandbox Code Playgroud)

我们从代码中调用它:

Service service = ...
int a = service.calculate(); // calls calculate()I method
Run Code Online (Sandbox Code Playgroud)

在版本 v1.1 中,库代码略有更改:

// jar v1.1 
interface Service {
   Integer calculate(); // signature: ()Ljava.lang.Integer;
}
Run Code Online (Sandbox Code Playgroud)

由于自动装箱,源代码仍然兼容,但是如果我们使用新的库版本运行代码,它将失败并出现 java.lang.NoSuchMethodError: Service.calculate()I 错误。

类似的问题可能是由 lambda 作用域、泛型转换、隐式类型转换等引起的。