一文總結Java\JDK 17釋出的新特性

語言: CN / TW / HK

JDK 17已經於2021年3月16日如期釋出。本文介紹JDK 17新特性。JDK 17於2021年9月14日正式釋出(General-Availability Release)。JDK 17將是大多數供應商的長期支援(LMS)版本。上一個LTS版本是JDK 11。

本文總結了JDK 17釋出的新特性。

釋出版本說明

根據釋出的規劃,這次釋出的 JDK 17 將是一個長期支援版(LTS 版)。LTS 版每 3 年釋出一個,上一次長期支援版是 18 年 9 月釋出的 JDK 11。

JDK 17是Java SE平臺版本17的開源參考實現,由JSR 392在JCP(Java Community Process)指定。

安裝包下載

主要分為OpenJDK版本和Oracle版本,下載地址如下:

上述版本,如果是個人學習用途,則差異不大。但如果是用於商業用途,則需要仔細看好相關的授權。Oracle JDK根據二進位制程式碼許可協議獲得許可,而OpenJDK根據GPL v2許可獲得許可。

更多有關Java的基本知識,可以參閱《Java核心程式設計》這本書,描述的非常詳細。

JDK 17 新特性說明

JEP 406:switch的模式匹配(預覽)(JDK-8213076)

specification

通過switch表示式和語句的模式匹配,以及模式語言的擴充套件,增強Java程式語言。將模式匹配擴充套件到switch允許對錶達式進行測試,每個模式都有特定的操作,以便可以簡潔而安全地表達複雜的面向資料的查詢。

有關更多詳細資訊,請參見JEP 406

JEP 409:密封類(JDK-8260514)

specification

密封類(Sealed Class)已新增到Java語言中。密封類和介面限制了哪些其他類或介面可以擴充套件或實現它們。

密封類由JEP 360並在JDK 15中作為預覽功能交付。它們再次被提出,並進行了改進,由JEP 397並在JDK 16中作為預覽功能提供。現在,在JDK 17中,密封類正在最終確定,與JDK 16沒有任何更改。

有關更多詳細資訊,請參見JEP 409

JEP 382:新的macOS渲染管道(JDK-8238361)

client-libs/2d

Swing API用於渲染的Java 2D API現在可以使用新的Apple Metal加速渲染API 給macOS。

目前預設情況下,這是禁用的,因此渲染仍然使用OpenGL API,這些API被Apple棄用,但仍然可用和支援。

要啟用金屬,應用程式應通過設定系統屬性指定其使用:

-Dsun.java2d.metal=true

Metal或OpenGL的使用對應用程式是透明的,因為這是內部實現的區別,對Java API沒有影響。Metal管道需要macOS 10.14.x或更高版本。在早期版本上設定它的嘗試將被忽略。

有關更多詳細資訊,請參見[JEP 382(https://openjdk.java.net/jeps/382)

大圖示訪問新API(JDK-8182043)

client-libs/javax.swing

JDK 17中提供了一個新的方法javax.swing.filechooser.FileSystemView.getSystemIcon(File, int, int),該方法允許在可能的情況下訪問更高質量的圖示。它已為Windows平臺完全實施;但是,其他平臺上的結果可能會有所不同,稍後將增強。例如,通過使用以下程式碼:

FileSystemView fsv = FileSystemView.getFileSystemView();

Icon icon = fsv.getSystemIcon(new File("application.exe"), 64, 64);

JLabel label = new JLabel(icon);

使用者可以為“application.exe”檔案獲得更高質量的圖示。此圖示適用於建立可以在HighDPI環境中更好地擴充套件的標籤。

DatagramSocket可以直接加入多播組(JDK-8237352)

core-libs/java.net

java.net.DatagramSocket在此版本中已更新,以新增對加入多播組(multicast group)的支援。它現在定義了加入和離開多播組的加入組和離開組方法。java.net.DatagramSocket的類級API文件已更新,以解釋如何配置普通DatagramSocket並用於加入和離開多播組。

此更改意味著DatagramSocket API可以用於組播應用程式,而無需使用舊的java.net.MulticastSocket API。MulticastSocket API的工作原理和以前一樣,儘管它的大多數方法都被棄用了。

有關此變更理由的更多資訊,請檢視CSRJDK-8260667

JEP 356:增強型偽隨機數生成器(JDK-8193209)

core-libs/java.util

為偽隨機數生成器(PRNG)提供新的介面型別和實現,包括可跳轉的PRNG和一類額外的可拆分PRNG演算法(LXM)。

有關更多詳細資訊,請參見JEP 356

Ideal Graph Visualizer的現代化(JDK-8254145)

hotspot/compiler

Ideal Graph Visualizer(IGV)是一個視覺化和互動式地探索HotSpot VM C2即時(JIT)編譯器中使用的中間表示的工具,已經現代化。增強功能包括:

  • 支援在最多JDK 15上執行IGV(IGV底層NetBeans平臺支援的最新版本)
  • 更快的、基於Maven的IGV構建系統
  • 塊形成、組刪除和節點跟蹤的穩定
  • 預設過濾器中更直觀的著色和節點分類
  • 具有更自然預設行為的排名快速節點搜尋

現代化的IGV部分相容從早期JDK版本生成的圖形。它支援基本功能,如圖形載入和視覺化,但輔助功能,如節點聚類和著色可能會受到影響。

有關構建和執行IGV的詳細資訊,請參見https://github.com/openjdk/jdk17/tree/master/src/utils/IdealGraphVisualizer

“New API”的新頁面和改進的“Deprecated”頁(JDK-8263468)

tools/javadoc(tool)

JavaDoc現在可以生成一個頁面,總結API中最近的更改。要包括的最近版本的列表是使用 --since命令列選項指定的。這些值用於查詢具有匹配@since的宣告,因為要包含在新頁面上的標記。--since-label命令列選項提供了要在“New API”頁面標題中使用的文字。

在總結已棄用專案的頁面上,您可以檢視按已棄用專案的版本分組的專案。

錯誤訊息中的源詳細資訊(JDK-8267126)

tools/javadoc(tool)

當JavaDoc報告輸入原始檔中的問題時,它將以類似編譯器(javac)診斷訊息的方式顯示問題的源行,以及包含指向該行位置的插入符號(^)的行。

此外,日誌記錄和其他“資訊”訊息現在寫入標準錯誤流,留下標準輸出流用於命令列選項特別請求的輸出,如命令列幫助。

JEP 412:外部函式和記憶體API(孵化)(JDK-8265033)

core-libs

引入一個API,Java程式可以通過該API與Java執行時之外的程式碼和資料互操作。通過有效地呼叫外部函式(即JVM外部的程式碼),並通過安全地訪問外部記憶體(即不由JVM管理的記憶體),該API使Java程式能夠呼叫本機庫並處理本機資料,而不會有JNI的脆弱性和危險。

有關更多詳細資訊,請參閱JEP 412

控制檯字符集API(JDK-8264208)

core-libs

java.io.Console已更新,以定義一個新方法,該方法返回控制檯的Charset。返回的Charset可能與Charset.defaultCharset()方法返回的Charset不同。例如,它返回IBM437,而Charset.defaultCharset()在Windows (en-US)上返回windows-1252。請參閱https://bugs.openjdk.java.net/browse/JDK-8264209瞭解更多詳細資訊。

用於反序列化的JDK Flight Recorder事件(JDK-8261160)

core-libs/java.io:serialization

現在可以使用JDK Flight Recorder (JFR)監控物件的反序列化。當啟用JFR且JFR配置包括反序列化事件時,每當執行程式嘗試反序列化物件時,JFR將發出事件。反序列化事件名為jfr.Derialization,預設情況下禁用。反序列化事件包含序列化篩選器機制使用的資訊;請參閱物件輸入篩選器規範。此外,如果啟用了過濾器,JFR事件指示過濾器是接受還是拒絕物件的反序列化。有關如何使用JFR反序列化事件的更多資訊,請參閱文章監控反序列化提高應用安全性。有關使用和配置JFR的參考資訊,請參閱JFR執行時指南和JFR命令參考JDK任務控制檔案的章節。

JEP 415:實現特定於上下文的反序列化過濾器(JDK-8264859)

core-libs/java.io:serialization

JEP 415:特定於上下文的反序列化過濾器允許應用程式通過JVM範圍的過濾器工廠配置特定於上下文的和動態選擇的反序列化過濾器,該工廠被呼叫以為每個單獨的反序列化操作選擇過濾器。

用於序列化過濾的Java核心庫開發人員指南介紹了用例,並提供了示例。

本機字元編碼名稱的系統屬性(JDK-8265989)

core-libs/java.lang

引入了一個新的系統屬性本機.encode。此係統屬性提供基礎主機環境的字元編碼名稱。例如,它通常在Linux和macOS平臺中具有UTF-8,在Windows (en-US)中具有Cp1252。請參閱https://bugs.openjdk.java.net/browse/JDK-8266075瞭解更多詳細資訊。

新增java.time.InstantSource (JDK-8266846)

core-libs/java.time

引入了一個新的介面java.time.InstantSource。此介面是java.time.Clock的抽象,只關注當前時刻,不引用時區。

十六進位制格式和解析實用程式(JDK-8251989)

core-libs/java.util

java.util.HexFormat為基元型別和位元組陣列提供十六進位制和十六進位制之間的轉換。分隔符、字首、字尾和大寫或小寫的選項由返回HexFormat例項的工廠方法提供。

實驗Compiler Blackholes支援(JDK-8259316)

hotspot/compiler

增加了對Compiler Blackholes的實驗支援。這些對於低階基準測試非常有用,以避免關鍵路徑上的死程式碼消除,而不影響基準效能。當前的支援以CompileCommand的形式實現,可訪問為-XX:CompileCommand=blackhole,<method>,並計劃最終將其畢業到公共API。

JMH已經能夠在指示/可用時自動檢測和使用此設施。有關後續步驟,請查閱JMH文件。

HotSpot JVM中的新類層次結構分析實現(JDK-8266074)

hotspot/compiler

HotSpot JVM中引入了一個新的類層次結構分析實現。它的特點是對抽象和預設方法的增強處理,從而改進了JIT編譯器所做的內聯決策。新實現將取代原始實現,並在預設情況下開啟。

為了幫助診斷與新實現相關的可能問題,可以通過指定 -XX:+UnlockDiagnosticVMOptions -XX:-UseVtableBasedCHA命令列標誌來開啟原始實現。

原始實現可能會在未來的版本中刪除。

JEP 391: macOS/AArch64埠(JDK-8251280)

hotspot/compiler

macOS 11.0現在支援AArch64體系結構。此JEP在JDK中實現了對macos-aarch64平臺的支援。新增的功能之一是支援W^X(write xor execute)記憶體。它僅對macos-aarch64啟用,並可以在某些時候擴充套件到其他平臺。JDK可以在英特爾計算機上交叉編譯,也可以在基於Apple M1的計算機上編譯。

有關更多詳細資訊,請參見JEP 391

統一日誌支援非同步日誌重新整理(JDK-8229517)

hotspot/runtime

為了避免使用統一日誌記錄的執行緒中出現不希望的延遲,使用者現在可以請求統一日誌記錄系統在非同步模式下執行。這可以通過傳遞命令列選項-Xlog:async來完成。在非同步日誌記錄模式下,日誌站點將所有日誌記錄訊息入隊到緩衝區。獨立執行緒負責將它們重新整理到相應的輸出。中間緩衝區是有界的。緩衝區耗盡時,入隊訊息將被丟棄。使用者可以使用命令列選項-XX:AsyncLogBufferSize=<bytes>.來控制中間緩衝區的大小。

ARM上的macOS早期訪問可用(JDK-8266858)

infrastructure/build

新的macOS現在可用於ARM系統。ARM埠的行為應與英特爾埠類似。沒有已知的功能差異。在macOS上報告問題時,請指定是使用ARM還是x64。

支援在Keytool -genkeypair命令中指定簽名者(JDK-8260693)

security-libs/java.security

-signer和-signerkeypass選項已新增到keytool實用程式的-genkey對命令中。-signer選項指定簽名者的私鑰條目的金鑰庫別名,-signerkeypass選項指定用於保護簽名者私鑰的密碼。這些選項允許keytool -genkey對使用簽名者的私鑰對證書進行簽名。這對於生成具有金鑰協商演算法作為公鑰演算法的證書特別有用。

SunJCE提供程式通過AES密碼支援KW和KWP模式(JDK-8248268)

security-libs/javax.crypto

SunJCE提供程式已得到增強,以支援AES金鑰換行演算法(RFC 3394)和帶填充演算法的AES金鑰換行演算法(RFC 5649)。在早期版本中,SunJCE提供程式在“AESWrap”密碼演算法下支援RFC 3394,該演算法只能用於包裝和解包裝金鑰。通過此增強,增加了兩種分組密碼模式,KW和KWP,支援使用AES進行資料加密/解密和金鑰包裝/解包裝。有關更多詳細資訊,請檢視“JDK提供程式文件”指南的“SunJCE提供程式”部分。

新SunPKCS11配置屬性(JDK-8240256)

security-libs/javax.crypto:pkcs11

SunPKCS11提供程式添加了新的提供程式配置屬性,以更好地控制本機資源的使用。SunPKCS11提供程式使用本機資源以便與本機PKCS11庫一起工作。為了管理和更好地控制本機資源,添加了額外的配置屬性,以控制清除本機引用的頻率,以及是否在登出後銷燬基礎PKCS11令牌。

SunPKCS11提供程式配置檔案的3個新屬性是:

  • destroyTokenAfterLogout (布林值,預設值為false)如果設定為true,則在SunPKCS11提供程式例項上呼叫java.security.AuthProvider.logout() 時,基礎令牌物件將被銷燬,資源將被釋放。這基本上會在logout() 呼叫後使SunPKCS11提供程式例項不可用。請注意,不應將此屬性設定為true的PKCS11提供程式新增到系統提供程式列表中,因為提供程式物件在logout() 方法呼叫後不可用。
  • cleaner.shortInterval(整數,預設值為2000,以毫秒為單位)這定義了在繁忙期間清除本機引用的頻率,即cleaner執行緒應多久處理佇列中不再需要的本機引用以釋放本機記憶體。請注意,cleaner執行緒將在200次失敗嘗試後切換到“longInterval”頻率,即在佇列中找不到引用時。
  • cleaner.longInterval(整數,預設值為60000,以毫秒為單位)這定義了在非繁忙期間檢查本機引用的頻率,即cleaner執行緒應檢查佇列中的本機引用的頻率。請注意,如果檢測到用於清理的本機PKCS11引用,cleaner執行緒將切換回“短間隔”值。

具有系統屬性的可配置擴充套件(JDK-8217633)

security-libs/javax.net.ssl

已新增兩個新的系統屬性。系統屬性jdk.tls.client.disableExts用於禁用客戶端中使用的TLS擴充套件。系統屬性jdk.tls.server.disableExts用於禁用伺服器中使用的TLS擴充套件。如果禁用了擴充套件,則在握手訊息中既不會生成也不會處理擴充套件。

屬性字串是在IANA文件中註冊的逗號分隔的標準TLS副檔名稱列表(例如,server_name、status_request和簽名_algorithms_cert)。請注意,副檔名區分大小寫。未知、不支援、拼寫錯誤和重複的TLS副檔名稱令牌將被忽略。

請注意,阻止TLS擴充套件的影響是複雜的。例如,如果禁用了強制擴充套件,則可能無法建立TLS連線。請不要禁用強制擴充套件,除非您清楚地瞭解其影響,否則不要使用此功能。

包摘要頁面上的“Related Packages”(JDK-8260388)

tools/javadoc(tool)

軟體包的摘要頁面現在包括一個列出任何“Related Packages”的部分。Related Packages(相關軟體包)是根據常見命名約定啟發式確定的,可能包括以下內容:

  • “parent”包(即,包是子包的包)
  • 同級包(即具有相同父包的其他包)
  • 任何子包

相關軟體包不一定都在同一個模組中。

參考引用