目錄
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(官方規格):目前處於第八個孵化階段,目標是處理向量計算,能夠可靠地執行並在受支援的 CPU 架構下最佳化向量指令
- JEP 474 ZGC 預設改為分代模式(官方規格):將 ZGC 的預設模式切換為「分代模式」並棄用「未分代模式」
除了上述所列的預覽功能之外,JDK 24 第一個出爐的新功能是 JEP 472 Prepare to Restrict the Use of JNI(限制 JNI 使用的準備)。
JDK 24 首項功能:JEP 472 簡介
JEP 472 的任務是「限制 Java Native Interface 使用」的準備工作。當我們使用 JNI 時,JVM 就會發出警告。JDK 22 中引入的JEP 454 外部函式和記憶體 API(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。
本篇文章的內容為老喬原創、二創或翻譯而來。雖已善盡校對、順稿與查核義務,但人非聖賢,多少仍會有疏漏之處難以避免。如果大家有任何問題、建議或指教,都歡迎在底下留言與老喬討論!