Java 9的javac
有一个新的标志--release
:
> javac --help
...
--release <release>
Compile for a specific VM version. Supported targets: 6, 7, 8, 9
它与-source
和-target
旗帜有什么不同?这只是-source X -target X
的捷径吗?
不完全是。
JEP 247: Compile for Older Platform Versions定义了这个新的命令行选项,--release
:
我们定义了一个新的命令行选项
--release
,它自动配置编译器以生成将链接到给定平台版本的实现的类文件。对于在javac
中预定义的平台,--release N
相当于-source N -target N -bootclasspath <bootclasspath-from-N>
。 (强调我的)
所以不,它不等于-source N -target N
。添加的原因在“动机”部分中说明:
javac
提供了两个命令行选项-source
和-target
,它们可以分别用于选择编译器接受的Java语言版本及其生成的类文件的版本。但是,默认情况下,javac
会针对最新版本的平台API进行编译。因此,编译的程序可能会意外地使用仅在当前版本的平台中可用的API。无论传递给-source
和-target
的值如何,此类程序都无法在较旧版本的平台上运行。选项。这是一个长期的可用性痛点,因为用户希望通过使用这些选项,他们将获得可以在指定平台版本上运行的类文件。
简而言之,指定源和目标选项不足以进行交叉编译。由于javac
默认情况下会针对最新的平台API进行编译,因此无法保证它们能够在旧版本上运行。您还需要指定与旧版本对应的-bootclasspath
选项以正确交叉编译。这将包括要编译的正确API版本并允许在旧版本上执行。由于经常被遗忘,因此决定添加一个命令行选项,该选项执行所有必要的操作以正确交叉编译。
进一步阅读in the mailing list和Oracle Docs。原始的bug被提交here。请注意,由于此选项的集成,JDK构建已捆绑了旧版本的平台API的描述,在“风险和假设”部分中提到。这意味着您无需在计算机上安装旧版本即可进行交叉编译。
--release X
不仅仅是-source X -target X
的捷径,因为-source
和-target
不足以安全地编译到旧版本。您还需要设置一个-bootclasspath
标志,该标志必须与旧版本相对应(并且这个标志经常被遗忘)。因此,在Java 9中他们制作了一个--release
标志,它取代了三个标志:-source
,-target
和-bootclasspath
。
所以,这是编译Java 1.7的一个例子:
javac --release 7 <source files>
请注意,您甚至不需要在计算机上安装JDK 7。 JDK 9已包含所需信息,以防止意外链接到JDK 7中不存在的符号。