目錄
JDK 24 現況
JDK 23(站內介紹)即將於今年 9 月份發布,緊接著後續的 JDK 24 開發工作也已如火如荼地展開,並預計於 2025 年 3 月發布。JDK 24 屬於非長期支援(LTS)的版本之一,這意味著它與 JDK 23 一樣,將只會獲得 Oracle 六個月的 Premier 支援。
可以預期的是,許多已包含在 JDK 23 中的預覽功能,都可望被納入 JDK 24 之中,例如像是:
- JEP 455 基礎型別的模式匹配:允許所有模式的上下文中使用基礎型別來增強模式匹配,並擴展
instanceof
和switch
以適用於所有基礎型別(規格) - JEP 477 隱含的已宣告類別和實例 Main 方法(站內介紹):預設的隱含類別,以及非靜態的 main 程式進入點(規格)
- JEP 480 結構化並行:簡化並行程式設計(規格)
- JEP 481 範圍值(站內介紹):用於分享不可變的資料(規格)
- JEP 482 彈性建構子主體:可在建構子函式中擁有更多的自由度(規格)
- JEP 466 類別檔 API:用於剖析、生成和轉換 Java 類別檔(規格)
- JEP 473 串流聚集器(站內介紹):增強 Stream API 以進行自訂的中間操作(規格)
- JEP 476 模組匯入宣告(站內介紹):用於匯入(
)模組匯出的所有套件並簡化模組程式庫的複用(規格)import - JEP 469 向量 API:目前在 JDK 23 中處於第八個孵化階段。它的目標是處理向量計算,能夠可靠地執行並在受支援的 CPU 架構下最佳化向量指令(規格)
- JEP 474 ZGC 預設改為分代模式(站內介紹):將 ZGC 的預設模式切換為「分代模式」並棄用「未分代模式」(規格)
除了上述所列的預覽功能之外,JDK 24 第一個出爐的新功能是 JEP 472 Prepare to Restrict the Use of JNI(限制 JNI 使用的準備)。
JEP 472 簡介
JEP 472 的任務是「限制 Java Native Interface 使用」的準備工作。當我們使用 JNI 時,JVM 就會發出警告。JDK 22 中引入的外部函式和記憶體 API(JEP 454 Foreign Function & Memory API,作為 JNI 替代方案)也同樣包含在內,因此使用 FFM API 時也會發出警告。其目的是幫助我們為未來的 Java 版本做好準備,並透過統一限制 JNI 和 FFM API 的使用來確保預設情況下的完整性。我們在必要時可以透過選擇性地指定選項來避免產生警告(現在階段)和禁止執行的限制(未來階段)。
該功能的目標有:
- 保留 JNI 作為與原生程式碼相互操作的標準方式
- 預設不允許與原生程式碼互動,無論是使用 JNI 或 FFM API,除非我們在程式啟動時明確指定啟用 JNI 或 FFM API
- 調整 JNI 和 FFM API 的使用,讓函式庫的維護人員能順利轉移而無需開發人員變更命令列選項
- 它並非要棄用 JNI,也並非要從 Java 平台中移除 JNI,同時也沒有要限制 JNI 呼叫原生程式碼
JNI 的問題
JNI 是在 JDK 1.1 時引入的,目的是做為 Java 程式碼與原生程式碼之間互相操作的主要方式。它允許 Java 程式碼呼叫原生程式碼(下行呼叫、downcall),以及原生程式碼呼叫 Java 程式碼(上行呼叫、upcall)。不幸的是,它們之間的任何交互操作都是有風險的,很可能會損害應用程式和 Java 平台本身的完整性。根據「預設情況下的完整性」政策,所有能夠破壞完整性的 JDK 功能都必須獲得開發人員的允許。下面列出了四種交互操作的風險:
- 下行呼叫可能導致任意的未定義行為,包括 JVM 當機。這些問題無法在 Java 執行時期預防,也無法拋出異常讓 Java 程式碼有機會去捕獲並處理
- 原生程式碼和 Java 程式碼之間經常利用直接位元組緩衝區交換資料,而這些緩衝區是垃圾收集器無法觸及的記憶體區域,最終變成了未受控管的灰色地帶。原生程式碼可能會產生一個無效記憶體區域的位元組緩衝區,如果在 Java 程式碼中使用它的話會導致未定義的行為
- 原生程式碼可以用 JNI 繞過 JVM 的存取檢查,像是直接存取欄位與呼叫方法。另外,原生程式碼甚至可以利用 JNI 在
final
欄位初始化很久之後去更改它們的值。因此,呼叫原生程式碼具有破壞 Java 程式碼完整性的風險存在 - 原生程式碼如果不正確使用某些 JNI 函數,可能導致垃圾收集器出現不良行為,而這種行為可能在程式的任何生命週期階段中發生。例如,存取臨界區域(critical region)但卻未釋放它,導致垃圾收集區無法回收物件
在 JDK 22 引入的 FFM API 一樣具有上述前二項的風險。採取的應對策略是將可能破壞完整性和不會破壞完整性的操作分開,因此 FFM API 之中有部分被歸類為受到限制的方法。這代表在程式執行時,我們必須使用 java 命令列選項去解開它們的封印。JNI 也應該要效仿 FFM API,以實現預設情況下的完整性。
後續版本
下一個 LTS 版本 JDK 25 預計將於 2025 年 9 月發布。以目前的使用現況來看,LTS 版本在 Java 社群中的使用比例佔據了極高的主導地位。以 New Relic 在今年 4 月的報告(來源)來看,至少有 98% 以上的用戶採用 Java LTS 版本,包括 8、11、17 和 21。這意味著 JDK 23 和 JDK 24 的採用率應該會非常低,因為大部分的用戶會期望使用 LTS,也就是接下來的 JDK 25。
本篇文章的內容為老喬原創、二創或翻譯而來。雖已善盡校對、順稿與查核義務,但人非聖賢,多少仍會有疏漏之處難以避免。如果大家有任何問題、建議或指教,都歡迎在底下留言與老喬討論!