Java 中的源兼容性是什么?
What is Source Compatibility in Java?
我正在阅读 Kinds of Compatibility 但我无法理解。有人可以解释一下吗?
据我所知,源兼容性似乎意味着用 X 编写的代码应该能够在 X+1 中编译。
但是,关于方法解析如何工作的更多细节似乎为其添加了更多细节,给人的印象是源兼容性不仅仅是能够在更高版本中编译。
能够使用 X+1 进行编译是最简单的源兼容性形式。
您 link 的文章定义了 3 个级别的源兼容性(如果算作“不兼容源”则为 4 个级别):
- 它仍然编译
- 它的编译和行为方式与 X 版本相同
- 它仍然可以编译并且编译成有效的相同二进制文件 (binary-preserving)
#1 很明显。
#2 可能会被破坏,因为如果你的库版本 X 有一个方法 foo(Object)
而你的源代码有一行显示 yourObject.foo("someString")
那么如果 X+1 添加了一个方法 foo(String)
然后针对 X+1 进行编译会将那个方法绑定到新方法而不是旧方法。
如果使用 "someString"
调用 foo(Object)
与使用 "someString"
调用 foo(String)
具有相同的效果,那么 #2 仍然适用,因为它们产生相同的行为。
#3 是关于那个特定的区别:如果你的源现在调用另一个方法,那么这个级别就被打破了。如果你想针对较新的库进行编译并且仍然运行针对旧版本(Android 通常是这种情况),这可能很重要。
总的来说:
源兼容性 - 此源文件能否在当前环境中编译(存在必需的依赖项等)。
二进制兼容性 - 此编译字节码 运行 是否会在当前环境中成功(存在依赖性 classes/methods 等)。
行为兼容性——这个编译后的字节码在当前环境中的行为是否正确(相同的输入在依赖项中导致相同的输出)
Java 寻求保持源代码和编译字节码之间的向后兼容性。这意味着在Java 6 中编写和编译的程序应该运行 无缝地在Java 8 中。Java 语言的设计方式,并非所有class 都是是 'executables'。有些可能是实用程序 classes,具有可用于各种应用程序的功能。
如果实用程序 class 是 a.MyUtility,则可以使用 import a.* 在可执行模块中导入这些依赖项。但是,如果 import 正则表达式匹配了 2 个同名的 classes(例如:还有一个 import b.* 和一个 b.MyUtility class),将无法解析在执行时使用哪个 MyUtility class。
我正在阅读 Kinds of Compatibility 但我无法理解。有人可以解释一下吗?
据我所知,源兼容性似乎意味着用 X 编写的代码应该能够在 X+1 中编译。
但是,关于方法解析如何工作的更多细节似乎为其添加了更多细节,给人的印象是源兼容性不仅仅是能够在更高版本中编译。
能够使用 X+1 进行编译是最简单的源兼容性形式。
您 link 的文章定义了 3 个级别的源兼容性(如果算作“不兼容源”则为 4 个级别):
- 它仍然编译
- 它的编译和行为方式与 X 版本相同
- 它仍然可以编译并且编译成有效的相同二进制文件 (binary-preserving)
#1 很明显。
#2 可能会被破坏,因为如果你的库版本 X 有一个方法 foo(Object)
而你的源代码有一行显示 yourObject.foo("someString")
那么如果 X+1 添加了一个方法 foo(String)
然后针对 X+1 进行编译会将那个方法绑定到新方法而不是旧方法。
如果使用 "someString"
调用 foo(Object)
与使用 "someString"
调用 foo(String)
具有相同的效果,那么 #2 仍然适用,因为它们产生相同的行为。
#3 是关于那个特定的区别:如果你的源现在调用另一个方法,那么这个级别就被打破了。如果你想针对较新的库进行编译并且仍然运行针对旧版本(Android 通常是这种情况),这可能很重要。
总的来说:
源兼容性 - 此源文件能否在当前环境中编译(存在必需的依赖项等)。
二进制兼容性 - 此编译字节码 运行 是否会在当前环境中成功(存在依赖性 classes/methods 等)。
行为兼容性——这个编译后的字节码在当前环境中的行为是否正确(相同的输入在依赖项中导致相同的输出)
Java 寻求保持源代码和编译字节码之间的向后兼容性。这意味着在Java 6 中编写和编译的程序应该运行 无缝地在Java 8 中。Java 语言的设计方式,并非所有class 都是是 'executables'。有些可能是实用程序 classes,具有可用于各种应用程序的功能。
如果实用程序 class 是 a.MyUtility,则可以使用 import a.* 在可执行模块中导入这些依赖项。但是,如果 import 正则表达式匹配了 2 个同名的 classes(例如:还有一个 import b.* 和一个 b.MyUtility class),将无法解析在执行时使用哪个 MyUtility class。