Java 9编译器中的--release标志是什么?


85

Java 9javac具有一个新标志--release

> javac --help
...

--release <release>
    Compile for a specific VM version. Supported targets: 6, 7, 8, 9

-source-target标志有何不同?这只是它的捷径-source X -target X吗?


Answers:


106

不完全是。

JEP 247:较旧平台版本的编译定义了此新的命令行选项--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版本,并允许在较旧版本上执行。由于它经常被遗忘,因此决定添加一个命令行选项,该选项执行所有必要的操作以正确地进行交叉编译。

进一步阅读邮件列表Oracle文档。原始错误已在此处提交。请注意,由于集成了此选项,因此JDK构建与早期版本的平台API的描述捆绑在一起,在“风险和假设”部分中进行了提及。这意味着您不需要在计算机上安装旧版本即可进行交叉编译。


一个疑问,是否有可能在代码中使用jdk 9-11中的功能并且它仍可在Java运行时8上运行?
克里斯蒂亚诺

不,他们不会出现在JRE 8个二进制
盗贼

您如何看待“平台API”?在字节码级别上有东西吗?或与基础x86平台或OS API相关的内容?
Jose Cifuentes

2
@JoseCifuentes,此处为“平台API”提供了JDK API的版本(不带--release标记),该版本是从用于编译的JDK推断出来的,通常不同于您使用-source和定位的JDK -target。万一您碰巧使用从未在JDK中引入的类/方法,那么可能会给您带来麻烦。如果编译器选择了一种方法重载,而该方法重载是在较早版本中添加的,而不是先前打算使用的方法重载,因此这是非常微妙的,则它会破坏二进制兼容性。
奥利弗·冈萨

30

--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中不存在的符号。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.