“源兼容性”与“目标兼容性”?

sourceCompatibilitytargetCompatibility之间的关系/区别是什么? 当它们被设置为不同的值时会发生什么?

根据 分级文件:

sourceCompatibility是“编译 Java 源代码时使用的 Java 版本兼容性” targetCompatibility是“为其生成类的 Java 版本”

我的理解是,targetCompatibility将生成与特定版本的 Java 兼容的 Java 字节码,这是 sourceCompatibility功能的子集吗?

132609 次浏览

在 javac 中,targetCompatibilitysourceCompatibility映射到 -target release-source release。Source 基本上是源语言级别,target 是生成的字节码级别。

更多细节可以在 工具参考 用于 Java 8用于 Java11用于 Java17用于 Java19javac的交叉编译选项部分找到。

当你使用这些的时候要小心,我们已经被假设的人咬了。

仅仅因为您使用了1.5的 source Compability (或 targetCompatiability) ,并不意味着您总是可以使用 JDK 1.6编译代码,并期望它在 JDK 1.5下工作。问题在于可用的库。

如果您的代码碰巧调用了某个只能在 JDK 1.6中使用的方法,那么它仍然会使用目标 VM 的各种兼容性选项进行编译。但是当您运行它时,它将失败,因为不存在有问题的方法(您将得到 MethodNotFoundException 或 ClassNotFoundException)。

出于这个原因,我将兼容性设置与我正在构建的实际 Java 版本进行比较。如果不匹配,我就会失败。

Source 兼容性 = 指定用于编译 。爪哇文件的 Java 编程语言版本。 .g source 兼容性1.6 = 指定使用 Java 编程语言的1.6版来编译 。爪哇文件。

默认情况下,source Compatiability = “当前使用的 JVM 版本”和 targetCompatiability = source Compatiability

TargetCompatiability = 该选项确保生成的类文件将与 targetCompatiability 指定的 VM 兼容。注意,在大多数情况下,-target 选项的值是-source 选项的值; 在这种情况下,可以省略-target 选项。

类文件将在 targetCompatiability 指定的目标上以及在更高版本上运行,但不会在 VM 的早期版本上运行

在我看来,“ source 兼容性”意味着您可以在源代码中使用什么特性。例如,如果将 source Compatiability 设置为1.7,那么即使 jdk 版本为1.8,也不能使用 java 8中的一个新特性—— lambda 表达式。
至于“ targetCompatiability”,它意味着生成的类文件可以在哪个版本的 jre 上运行,如果将它设置为1.8,它可能无法在 jdk 1.7上成功运行,但它通常可以在更高版本的 jdk 上运行。

这些是 javac 命令的标志。

javac [options] [sourcefiles]


Options:
...
-source release - Specifies the version of source code accepted.
...
-target release - Generates class files for a specific VM version.
...

换句话说: 编写 source版本的代码并将类编译成 targetVM 版本。以便在其他工作站上运行,例如使用旧的 java 版本。

根据: https://docs.oracle.com/en/java/javase/11/tools/javac.html

对于 sourceCompatibilitytargetCompatibility有什么好处,已经有很多很好的解释,在这里可以找到一篇更好的文章 targetCompatibility0。但是我建议不使用 sourceCompatibilitytargetCompatibility,而是使用使 releasesourceCompatibility过时的 Gradle toolchain(参见 targetCompatibility1) ,并保证语言特性(sourceCompatibility)、字节码(targetCompatibility)和 Java-API/-库(release)将与 Java 版本相匹配。(唯一的缺点是 IDE 支持尚未完全建立,但正在建立中)。