Java 9 編譯器中的 –release 選項是什麼?

1. 概述

在本教程中,我們將了解 Java 9 的新命令行選項–release. –release N選項運行的 Java 編譯器會自動生成與 Java 版本 N 兼容的類文件*.*我們將討論此選項與現有編譯器命令行選項-source-target.

2. Need for—— release選項

為了理解需要 - release選項,讓我們考慮一個場景,我們需要使用 Java 8 編譯我們的代碼,並希望編譯後的類與 Java 7 兼容。

在 Java 9 之前,可以通過使用sourcetarget選項來實現這一點,其中

  • -source:指定編譯器接受的Java版本
  • -target:指定要生成的類文件的 Java 版本

假設編譯的程序使用在當前版本的平台(在我們的例子中是 Java 8)中專門可用的 API。在這種情況下,編譯的程序不能在 Java 7 等早期版本上運行,無論傳遞給 – source和 – 的值如何target選項。

此外,我們需要添加 – bootclasspath選項以及 – source和 – target才能在 Java 8 及以下版本中工作。

為了簡化這個交叉編譯問題,Java 9 引入了新選項—— release以簡化過程。

3.關係隨著-source和-target選項

根據JDK 定義–release N 可以擴展為:

  • 對於 N < 9, -source N -target N -bootclasspath
  • 對於 N >= 9, -source N -target N –system

以下是有關這些內部選項的一些詳細信息:

  • -bootclasspath:用於搜索引導類文件的目錄、JAR 檔案和 ZIP 檔案的分號分隔列表
  • system :覆蓋 Java 9 及更高版本的系統模塊的位置

此外,文檔化的 API 位於 $JDK_ROOT/lib/ct.sym ,這是一個 ZIP 文件,其中包含根據 Java 版本剝離的類文件。

對於 Java 版本 N<9,這些 API 包括從位於jre/lib/rt.jar和其他相關 jar 中的 jar 檢索的引導程序類。

對於 Java 版本 N >= 9,這些 API 包括從位於jdkpath/jmods/目錄中的 Java 模塊檢索的引導程序類。

4. 命令行使用

首先,讓我們創建一個示例類並使用 Java 9 中添加的ByteBuffer flip()

import java.nio.ByteBuffer;

 public class TestForRelease {

 public static void main(String[] args) {
 ByteBuffer bb = ByteBuffer.allocate(16);
 bb.flip();
 System.out.println("Baeldung: --release option test is successful");
 }
 }

4.1.使用現有的 -source 和 -target 選項

-source-target選項值為 8 來編譯 Java 9 中的代碼:

/jdk9path/bin/javac TestForRelease.java -source 8 -target 8

這樣做的結果是成功的,但有一個警告:

warning: [options] bootstrap class path not set in conjunction with -source 8

 1 warning

現在,讓我們在 Java 8 上運行我們的代碼:

/jdk8path/bin/java TestForRelease

我們看到這失敗了:

Exception in thread "main" java.lang.NoSuchMethodError: java.nio.ByteBuffer.flip()Ljava/nio/ByteBuffer;
 at com.corejava.TestForRelease.main(TestForRelease.java:9)

正如我們所看到的,這不是我們在-target選項中給定的 8 值所期望看到的。所以雖然編譯器應該考慮它,但事實並非如此。

讓我們更詳細地了解這一點。在編譯期間,我們收到了之前忽略的警告。這是因為 Java 編譯器默認使用最新的 API 進行編譯。換句話說,雖然我們提供的–source和- target選擇為8,是在Java的9類進行編譯。

因此,我們必須將另一個名為bootclasspath命令行選項傳遞給 Java 編譯器以選擇正確的版本。

現在,讓我們使用 – bootclasspath選項:

/jdk9path/bin/javac TestForRelease.java -source 8 -target 8 -Xbootclasspath ${jdk8path}/jre/lib/rt.jar

同樣,這樣做的結果是成功的,我們沒有警告。

現在,讓我們在 Java 8 上運行我們的代碼,我們看到這是成功的:

/jdk8path/bin/java TestForRelease
 Baeldung: --release option test is successful

儘管交叉編譯現在可以工作,但我們必須提供三個命令行選項。

4.2.帶 –release 選項

現在,讓我們使用–release選項編譯相同的代碼:

/jdk9path/bin/javac TestForRelease.java —-release 8

再次,這次編譯成功,沒有警告。

最後,當我們在 Java 8 上運行代碼時,我們看到它是成功的:

/jdk8path/bin/java TestForRelease
 Baeldung: --release option test is successful

我們看到,它是用簡單的- release選項, javac內部設置了正確的值-source, -target,和- bootclasspath.

5. 使用 Maven Compiler Plugin

通常,我們使用 Maven 或 Gradle 等構建工具,而不是命令行javac工具。因此,在本節中,我們將看到如何在 maven 編譯器插件中–release

讓我們首先看看我們如何使用現有的-source-target選項:

<plugins>
 <plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-compiler-plugin</artifactId>
 <version>3.8.1</version>
 <configuration>
 <source>1.8</source>
 <target>1.8</target>
 </configuration>
 </plugin>
 </plugins>

以下是我們如何使用–release選項:

<plugins>
 <plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-compiler-plugin</artifactId>
 <version>3.8.1</version>
 <configuration>
 <release>1.8</release>
 </configuration>
 </plugin>
 </plugins>

儘管行為與我們之前描述的相同,但我們將這些值傳遞給 Java 編譯器的方式是不同的。

六,結論

在本文中,我們了解了–release選項及其與現有-source-target選項的關係。然後,我們看到瞭如何在命令行和 Maven 編譯器插件中使用該選項。

最後,我們看到新的 - release選項需要更少的交叉編譯輸入選項。因此,建議盡可能使用它來代替-target, -source,-bootclasspath選項.