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
吗?
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:
不完全是。
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的描述捆绑在一起,在“风险和假设”部分中进行了提及。这意味着您不需要在计算机上安装旧版本即可进行交叉编译。
--release
标记),该版本是从用于编译的JDK推断出来的,通常不同于您使用-source
和定位的JDK -target
。万一您碰巧使用从未在JDK中引入的类/方法,那么可能会给您带来麻烦。如果编译器选择了一种方法重载,而该方法重载是在较早版本中添加的,而不是先前打算使用的方法重载,因此这是非常微妙的,则它会破坏二进制兼容性。
--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中不存在的符号。