JavaRush /Java Blog /Random-TW /Java 14:有什麼新變化?

Java 14:有什麼新變化?

在 Random-TW 群組發布
世界的問題就是世界的問題,新的Java如期而至。也就是說,每六個月一次。Java 14 的發布版本於 3 月 17 日發布,針對開發人員為該語言引入了幾項有趣的創新。 其中包括對recordJava 14:有什麼新變化? - 1關鍵字的實驗性支援、對「 instanceof 」運算子中的模式匹配的支援、更用戶友好的NullPointerExceptions 、擴展的文字區塊「預覽」、更新的預設開關等等。讓我們提醒您,Java 中的所有創新都始於擴展提案(JEP,Java 增強提案)。開發人員提出更改,由「官方」Java 父輩進行審查,然後其中一些更改被接受,之後它們就成為 JDK 的一部分。現在——一切都井然有序。

JEP 359:記錄

Records,也稱為 Records,在 JDK 14 中以預覽模式提供,這對 Java 來說是全新的東西。事實上,我們面前有一種在瓦爾哈拉計畫期間開發的新型。記錄與枚舉類似,可以讓您簡化程式碼。本質上,它們取代了具有狀態但沒有行為的類別。簡單來說,有字段,沒有方法。就類別而言,我們有時必須編寫大量不總是必要的重複程式碼:建構函式、存取器、equals()、hashCode()、toString()等。為了避免這種重複程式碼,Java 計劃使用記錄。這是經典版本:
final class Triangle {
 	public final int x;
public final int y;
public final int z;

    public Triangle(int x, int y, int z) {
         this.x = x;
         this.y = y;
    this.z = z;
    }
    // equals, hashCode, toString
讓我們轉向 Java 14 並使用記錄:
public record Triangle(int x, int y, int z){}
就這樣。請注意,錄音目前以預覽形式存在,因此要在實踐中嘗試它們,您需要下載 jdk14 並輸入命令:
javac —enable-preview —release 14 Triangle.java
記錄是類,儘管有限制。它們不能擴展其他類別或聲明欄位(除了對應於狀態聲明元件的私有final)。記錄是隱式最終的並且不能是抽象的。記錄與常規類別的不同之處在於它們無法將其 API 與其表示形式分開。但準確性的提高彌補了自由度的損失。記錄組件也是隱式最終的。

JEP 305:instanceof 的模式匹配(預覽版)

Java 14 預覽版中引入的模式匹配功能旨在將物件類型檢查及其在instanceof運算符中的轉換結合起來。換句話說,在 Java 14 之前,會有以下程式碼:
Object object = Violin;

if (object instanceof Instrument) {
    Instrument instrument = (Instrument) object;
    System.out.println(instrument.getMaster());
}
正如您所看到的,我們必須將物件強制轉換為我們要使用其方法的類別。現在,Java 14 和連接的模式匹配功能可讓您將程式碼縮減為以下內容:
Object object = Violin;

if (object instanceof Instrument instrument){
    System.out.println(instrument.getMaster());
}

JEP 343:打包工具(孵化器)

JDK 8 有一個專為 JavaFX 設計的javapackager工具。然而,隨著 JDK 11 的發布,JavaFX 與 Java 分離,流行的 javapackager 不再可用。 Javapackager是一個打包工具。它允許 Java 應用程式以這樣的方式打包,以便可以像所有其他「正常」程式一樣安裝它們。例如,為 Windows 使用者建立 exe 文件,然後像人類一樣雙擊啟動 Java 應用程式。當然,這樣的工具非常缺乏,因此JEP 343引入了一個新工具jpackage,它將 Java 應用程式打包到包含所有必要依賴項的特定於平台的套件中。特定平台支援的套件格式:
  • Linux:deb 和 rpm
  • macOS:pkg 和 dmg
  • Windows:MSI 和 EXE

JEP 345:G1 的 NUMA 感知記憶體分配

JEP 345 僅用於實現 NUMA(非均勻記憶體存取)支援。這些是異質記憶體存取架構,是一種將微處理器叢集設定為多處理器系統的方法,其中記憶體可以本地分佈:每個處理器核心獲得少量本地內存,而其他核心可以存取它。JEP 345 計畫為 G1 垃圾收集器配備利用此類架構的能力。除此之外,這種方法有助於提高功能強大的機器的性能。

JEP 349:JFR 事件流

Java Flight Recorder (JFR)現在是 OpenJDK 的一部分,因此可以免費使用。JDK 14 新增了一個用於動態追蹤 JFR 事件的 API(JDK Flight Recorder),特別是用於組織對活動和非活動應用程式的持續監控。記錄的事件與非流選項相同,開銷不到 1%。這樣,事件將與非串流選項同時進行串流傳輸。但是,JEP 349 不得允許相應使用者的同步回呼。即使是儲存在中間記憶體中的記錄中的資料也不應該是可存取的。從技術上講,jdk.jfr 模組中的 jdk.jfr.consumer 套件將擴展非同步存取事件的功能。

JEP 352:非揮發性映射位元組緩衝區

眾所周知,Java NIO(新IO)檔案API從JDK 1.4開始就已經存在,然後引入了一個名為Path的新增強功能。Path 是一個接口,當我們在 Java NIO 中工作時,它會取代 java.io.File 類別來表示檔案或目錄。JEP 352 擴充了 MappedByteBuffer 以將一部分檔案資料載入到非揮發性記憶體 (NVM) 中。這種即使斷電資料也不會遺失的電腦記憶體(通常稱為唯讀記憶體)用於永久儲存資料。這個Java增強提案為JDK API提供了一個新的模組和類別:jdk.nio.mapmode模組,它提供了新的模式(READ_ONLY_SYNC、WRITE_ONLY_SYNC)來建立引用NVM的映射位元組緩衝區(MappedByteBuffer)。

JEP 358:有用的 NullPointerExceptions

NullPointerExceptions現在對程式設計師更加友善。從某種意義上說,異常的描述將比以前提供更多資訊。這是因為 JVM 被教導能夠更準確地分析程式字節碼指令,並且它可以指示哪個變數導致零值。假設我們有程式碼:
a.getMessage().getUserInfo().getName()
在任何最新的 Java 中,我們都會得到常見的錯誤日誌,它並沒有回答到底誰是 null 的問題:
Exception in thread "main" java.lang.NullPointerException
	at Main.main(Main.java:12)
如果您決定嘗試此預覽功能,Java 14 將為您提供以下功能:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "UserInfo().getName()" because the return value of "Message().getUserInfo()" is null
	at Main.main(Main.java:12)
該鏈更容易理解,並且可以讓您更快地解決錯誤。

JEP 361:開關表達式(標準)

更新後的 Switch 運算子已在先前的 Java 12 和 13 中提供,但僅作為預覽功能,即預設不啟用。現在,在 JDK 14 中,一切都可以開箱即用。Java 14 引入了帶有 case L -> ... 標籤的 switch 區塊的新簡化形式。新形式在某些情況下簡化了程式碼。這裡有幾個例子。假設我們有一個描述一週中的日子的列舉。我們可以寫經典程式碼(Java 14 之前的版本):
switch (day) {
    case MONDAY:
    case FRIDAY:
    case SUNDAY:
        System.out.println(6);
        break;
    case TUESDAY:
        System.out.println(7);
        break;
    case THURSDAY:
    case SATURDAY:
        System.out.println(8);
        break;
    case WEDNESDAY:
        System.out.println(9);
        break;
}
這是使用 Java 14 的選項:
switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);
    case TUESDAY                -> System.out.println(7);
    case THURSDAY, SATURDAY     -> System.out.println(8);
    case WEDNESDAY              -> System.out.println(9);
}
您也可以編寫多行區塊並使用新的yield關鍵字傳回一個值:
int result = switch (s) {
    case "Working from Home" -> 1;
    case "Working from Office" -> 2;
    default    -> {
        System.out.println("Neither Home nor Office… Cafe? Car? Park?...");
        yield 0;
    }
};
使用新開關 時,還有一些更重要的事情要記住。特別是,您需要記住選項必須是詳盡的。也就是說,對於所有可能的值都必須有一個對應的開關標籤。由於yield現在是一個關鍵字,因此在Java 14中可以有一個名為yield的類別。一般來說,如果您想學習如何使用更新的開關,請前往JEP 361並學習。那裡有很多有趣的資訊。

JEP 362:棄用 Solaris 和 SPARC 端口

我們的許多讀者不太可能記得Solaris作業系統。這個基於 UNIX 的作業系統,由 Java 的父母 Sun Microsystems 創建,主要用於 SPARC 架構上的伺服器...... 每平方厘米有太多陌生的單字?沒什麼大不了的:JEP 362 終止了對 Solaris/SPARC、Solaris/x64 和 Linux/SPARC 平台的支援。也就是說,它們的連接埠現在已棄用,將來它們很可能會從 OpenJDK 中刪除。但是,有關 Solaris/SPARC、Solaris/x64 和 Linux/SPARC 連接埠的舊版 Java(JDK 14 之前的版本)無需修改即可運行。如果您是歷史愛好者並且對不遠的過去的技術感興趣,請訪問維基百科並閱讀有關SPARС架構的資訊。

JEP 363:刪除並發標記掃描 (CMS) 垃圾收集器

CMS 垃圾收集器(並發標記清除)是被刪除的目標,因為它在兩年前被標記為過時且無人維護。然而,使用 CMS GC 的舊版 Java 使用者可能會鬆口氣——這個 JEP 的目的並不是從早期 JDK 版本中刪除建置器。此外,ParallelScavenge 和 SerialOld 垃圾收集演算法的組合(使用“-XX:+UseParallelGC -XX:-UseParallelOldGC”選項運行)已被棄用。

JEP 364:macOS 上的 ZGCJEP 365:Windows 上的 ZGC

有一個有趣的垃圾收集器,稱為Z 垃圾收集器 (ZGC)。它工作在被動模式下,並儘量減少垃圾收集造成的延遲:使用 ZGC 時的停止時間不超過 10 ms。它可以處理小堆和巨型堆(佔用許多 TB 的堆)。JEP 364 和 JEP 365 實際上是雙胞胎。JEP 364 將 Z 垃圾收集器引入 MacOS。JEP 的一部分也描述了用於釋放未使用的裝置記憶體的收集器功能,如JEP 351中所指定,這在 Java 13 中發生。macOS 上的 ZGC 實作由兩部分組成:
  • macOS 上的多重映射記憶體支持
  • ZGC 支援連續記憶體預留
JEP 365 已經在 Windows 上提供了對 ZGC 的支持,並且還處於實驗模式。如下:
  • 多映射記憶體支援
  • 支援基於頁面檔案的記憶體映射到保留的位址空間
  • 支援映射和取消映射堆的任意部分
  • 支援提交和取消提交堆的任意部分

JEP 366:棄用 ParallelScavenge + SerialOld GC 組合

此 JEP 不贊成並行 Scavenge 和串列舊垃圾收集演算法的組合。必須使用命令列參數 -XX: + UseParallelGC -XX: -UseParallelOldGC 手動啟用此組合。作者認為這種組合非常具體,但也需要大量的維護工作。因此,現在 -XX: UseParallelOldGC 選項已被棄用,如果使用,將會出現警告。

JEP 367:刪除 Pack200 工具和 API

Pack200是一種針對儲存已編譯的 Java 類別檔案而最佳化的存檔格式。該工具自 Java 11 起已被標記為已棄用。現在 pack200、unpack200 和 Pack200 API 工具已正式宣布從 java.util.jar套件中刪除。這項技術早在 Java 5 中就被引入,作為一種處理非常有限的頻寬(調製解調器,說起來可怕,記住,56k)和硬碟上儲存空間不足的方法。不久前,Java 9 引進了新的壓縮方案。鼓勵開發人員使用jlink

JEP 368:文字區塊(第二次預覽)

文字區塊首次出現在 Java 13 中。它們是多行字串文字,不需要大多數轉​​義序列,自動格式化字串,並且還允許開發人員在必要時格式化字串。這個有用的功能現在在 Java 14(第二個預覽版)中可用。文字區塊的主要目的是改進對令人困惑的多行文字的處理。這大大簡化了 SQL 查詢、HTML 和 XML 程式碼以及 JSON 的讀寫。沒有文字區塊的 HTML 範例:
String html = "<html>\n" +
              "    <body>\n" +
              "        <p>Hello, JavaRush Student</p>\n" +
              "    </body>\n" +
              "</html>\n";
如何用文字區塊表示相同的內容:
String html = """
              <html>
                  <body>
                      <p>Hello, JavaRush Student</p>
                  </body>
              </html>
              """;
開始分隔符號是三個雙引號字元 ("" ") 的序列,後面跟著零個或多個空格,然後是行分隔符號。內容從開始分隔符號的行分隔符號之後的第一個字元開始。結束分隔 是選擇三個雙引號字符 ,以便可以在不轉義的情況下顯示字符,並且還可以在視覺上區分文本塊和字符串文字。2019 年初,JEP 355 提議將文本區塊作為 JEP 326(原始字串文字)的延續,但已被撤回。同年晚些時候,JDK 13 引入了文字區塊預覽功能,現在 Java 14 新增了兩個新的轉義序列。這是一個行終止符,表示為 \,第二個是單一空格,表示為 /s。使用不含文字區塊的換行符的範例:
String literal = "This is major Tom to Ground Control " +
"I am stepping through the door... " +
"Wait… What???";
現在使用轉義序列 \<line-terminator>:
String text = """
                This is major Tom to Ground Control \
                I am stepping through the door... \
                WaitWhat???\
                """;
轉義序列\s用於解釋尾隨空白,預設編譯器會忽略該空白。它保留其前面的所有空白。例子:
String text1 = """
               line1
               line2 \s
               line3
               """;

String text2 = "line1\nline2 \nline3\n";
text1並且text2是相同的。

JEP 370:外部記憶體存取 API(孵化器)

許多流行的 Java 程式庫和程式都可以存取外部記憶體。例如,Ignite、MapDB、Memcached 和 Netty ByteBuf API。這樣做,他們可以避免與垃圾收集相關的成本和不可預測性(特別是在服務大型緩存時),跨多個進程共享內存,並通過在內存中映射文件(例如,使用mmap)來序列化和反序列化記憶體內容。然而,Java API仍然沒有合適的存取外部記憶體的解決方案。JDK 14 包含外部記憶體存取 API的預覽版,該 API 允許 Java 應用程式使用新的 MemorySegment、MemoryAddress 和 MemoryLayout 抽象化安全且有效率地存取 JVM 堆外部的記憶體區域。

結論

所以你怎麼看?與 Java 13 相比,新的 Java 14 在各個領域提供了許多更重要的改進。對於開發人員來說最重要的很可能是更新的開關、擴充異常 NullPointerExceptions 和記錄。或不是?..不要忘記嘗試Java 14的新功能,即使對於初學者來說它也非常有用。祝你學業順利!
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION