sourceCompatibility
和targetCompatibility
之间有什么关系/区别?当它们设置为不同的值时会发生什么?
sourceCompatibility
是“编译 Java 源代码时使用的 Java 版本兼容性。”targetCompatibility
是“为其生成类的 Java 版本。”我的理解是
targetCompatibility
将生成与特定版本的Java兼容的Java字节码。这是 sourceCompatibility
功能的子集吗?
targetCompatibility
和 sourceCompatibility
映射到 javac 中的 -target release
和 -source release
。源基本上是源语言级别,目标是生成的字节码级别。
更多详细信息可以在 工具参考
for Java 8、for Java 11、for Java 17、for Java 19 或 for 的
javac
部分的交叉编译选项中找到Java 21.
使用这些时要小心;我们被那些做出假设的人所困扰。
仅仅因为您使用 1.5 的 sourceCompatibility(或 targetCompatibility)并不意味着您始终可以使用 JDK 1.6 编译代码并期望它在 JDK 1.5 下工作。问题是可用的库。
如果您的代码碰巧调用了某些仅在 JDK 1.6 中可用的方法,它仍然会使用目标 VM 的各种兼容性选项进行编译。但是当你运行它时,它会失败,因为有问题的方法不存在(你将得到 MethodNotFoundException 或 ClassNotFoundException)。
因此,我总是将兼容性设置与我正在构建的实际 Java 版本进行比较。如果它们不匹配,我的构建就会失败。
sourceCompatibility = 指定用于编译 .java 文件的 Java 编程语言版本。 例如,sourceCompatibility 1.6 =指定使用 Java 编程语言 1.6 版本来编译 .java 文件。
默认情况下sourceCompatibility =“当前使用的JVM版本”和targetCompatibility = sourceCompatibility
targetCompatibility = 该选项确保生成的类文件与 targetCompatibility 指定的虚拟机兼容。请注意,大多数情况下,-target 选项的值就是-source 选项的值;在这种情况下,您可以省略 -target 选项。
类文件将在 targetCompatibility 指定的目标和更高版本上运行,但不能在早期版本的 VM 上运行
对于
sourceCompatibility
与 targetCompatibility
的优点,已经给出了很多很好的解释,可以在此处找到进一步的好文章 Gradle:sourceCompatibility 与 targetCompatibility。但我建议使用 Gradle sourceCompatibility
(请参阅JVM 项目的工具链)而不是
targetCompatibility
与 toolchain
,这使得 release
或 sourceCompatibility
调整过时,并保证语言功能 (sourceCompatibility
) )、字节码 (targetCompatibility
) 和 Java-API/-Libraries (release
) 将与 Java 版本匹配。 (唯一的缺点是 IDE 支持尚未完全建立,但正在进行中)。
在我看来,“sourceCompatibility”意味着你可以在源代码中使用什么功能。例如,如果你将sourceCompatibility设置为1.7,那么你就不能使用java 8中的新功能lambda表达式,即使你的jdk版本是 1.8。
至于“targetCompatibility”,表示生成的class文件可以在哪个版本的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
版本中编写代码,并将类编译为 target
VM 版本。为了运行它,例如在其他具有较旧 Java 版本的工作站上。
根据:https://docs.oracle.com/en/java/javase/11/tools/javac.html
除了很好的解释之外,请注意,在 gradle 网站 上,有一个大警告:
使用兼容性属性可能会导致运行时失败 由于它们提供的保证较弱而执行编译的代码。 相反,请考虑使用工具链或发布标志。