Java 25 LTS 長期支援版功能簡介

Java 25 Overview

2025 年是 Java 誕生的第 30 週年。這個陪伴無數開發者成長的程式語言迎來了新的里程碑,歷經兩年後的最新 LTS 長期支援版本:Java 25

作為最新的長期支援版,Java 25 預計將於 2025 年 9 月 16 日正式發布,並帶來十八項豐富的新功能與重要更新。其中包括了十一項正式功能、四項預覽功能、一項孵化器功能、一項實驗性功能,以及一項移除公告。

本文將簡介 Java 25 中的各項主要 JEP,範圍包含了效能優化、安全性、語法簡化、以及執行時期的監測增強。這些功能可望為 Java 開發人員提供更快速的性能優化方案,以及快速開發的能力。

前言

Java 25 目前已進入最終候選版本階段,並預計於兩週後正式發布。數項在 Java 24 中預覽或實驗性的功能,在本版中轉換成正式功能。其中包括了分代型 Shenandoah 垃圾收集器(JEP 521)和精簡物件標頭(JEP 519)可改善執行效能,以及加強安全性的金鑰衍生函式 API(JEP 510)。

在降低 Java 學習門檻或解除語言限制的部分,有範圍值(JEP 506)、彈性建構子主體(JEP 513)、模組匯入宣告(JEP 511),以及精簡原始檔與實例主方法(JEP 512)等等。

全新功能的部分則包括有安全性相關的隱私增強郵件編碼加密物件(JEP 470),和延遲不可變物件其初始化的穩定值(JEP 502)。另外,本版中也加入了預先編輯快取與 JDK 飛行紀錄器(JDK Flight Recorder)的數項增強功能,它們可有效提升程式載入效能,以及更全面的監控機制。

在 Java 25 中仍維持在預覽階段的功能,像是基礎型別的模式匹配(JEP 507)、向量 API(JEP 508)、結構化並行(JEP 507)等等,會持續收集意見後進行改善,並在未來的版本中釋出。

時程表

以下是本版計畫的時程表:

  • 2025 年 6 月 5 日:第一階段降溫(功能凍結加入並僅能移除、穩定性測試)
  • 2025 年 7 月 17 日:第二階段降溫(更嚴格的錯誤修復條件、測試與優化)
  • 2025 年 8 月 7 日:初始候選版本(完成新功能整合到主線、重點測試與修復)
  • 2025 年 8 月 21 日:最終候選版本
  • 2025 年 9 月 16 日:正式發布

如同 Java 24 發布時的介紹一樣,老喬會儘可能地說明 Java 25 中每項正式功能,並用快速導覽的方式簡介本版中幾個較重要的預覽功能和改進項目,而不會逐篇完整說明。

語言改進

JEP 507:模式、instanceof 與 switch 中的基礎型別匹配(第四次預覽)

此功能進入第四次預覽階段,其前身為 JEP 455JEP 488。本次為延續預覽階段並收集更多意見,沒有任何規格變更,因此下方延用之前的簡介

Java 25 的此功能解除了基礎型別在模式匹配中存在的幾個限制。處理基礎型別和物件型別的程式碼將會被簡化,不再需要特殊處理,使得這兩種型別可以用相同的方式應對。由於現在可以自動處理條件式轉型(值必須被檢查以確保它對目標型別有效),因此允許 instanceof 接受基礎型別的話可以進一步減少程式碼數量。

它增強了 Java 的模式匹配功能,並擴展 instanceofswitch,使其能夠在所有模式的上下文中使用基礎型別的模式匹配:

  • 基礎型別模式的增強:允許在模式匹配中適用更廣泛的候選基礎型別,例如 record Test(double d) 可以使用 x instanceof Test(int i) 去判定 d 值是否能轉型成 int
  • instanceof 的擴展:允許 instanceof 運算符與基礎型別一起使用,例如 if (x instanceof int i) { ... }
  • switch 的擴展:允許 switch 表達式處理所有基礎型別,包括 booleanfloatdoublelong,例如 case byte b -> ...

JEP 511:模組匯入宣告(預覽轉正式)

此功能從預覽階段轉為正式功能,其前身為 JEP 476JEP 494。本次沒有任何規格變更,因此下方延用前一版簡介

它允許開發者透過單一陳述句去匯入模組中的所有公開型別,以簡化模組化函式庫的重複使用。有了這項功能,初學者便能更輕鬆地使用第三方函式庫和基礎 Java 類別,而無需學習它們在套件階層中的位置。它提供了簡潔的方式,將匯入類別與套件的語句簡化成匯入模組,以減少樣板程式碼撰寫:

  • 引入新的 import module 語句,允許一次性匯入模組中的所有型別。例如:import module java.base; 將匯入 java.base 模組中導出的所有套件
  • 新語句可以與現有的 import 語句共存,並且不會影響現有程式碼的行為

JEP 512:精簡原始檔和實例主方法(預覽轉正式)

此功能從預覽階段轉為正式功能,其前身為 JEP 477JEP 495。本次僅有 IO 類別的變更,因此下方延用前一版簡介並微幅修改

本功能讓初學者能夠輕鬆地撰寫第一個 Java 程式,而不需要先全部理解較為複雜的程式語法和功能。簡易的程式可以使用精簡的宣告方式運行,並且在需要時能夠無縫擴展去使用更高級的功能。經驗豐富的開發人員也可以享受簡潔地編寫小型程式的樂趣。

  • 隱式宣告類別:如果一個簡單 Java 原始檔中沒有使用 class 關鍵字明顯地宣告任何類別,編譯器會自動為該檔案建立一個隱式類別。類別名稱與檔案名稱相同(但不包括 .java 副檔名),並且它會是 final 且直接繼承自 Object
  • 實例主方法:允許在隱式宣告類別中定義一個非靜態的 main 方法,其方法簽章為 void main()void main(String[] args)
  • 自動匯入:隱式宣告類別會自動 import module java.base 模組中的所有型別(請參考上一節模組匯入宣告的內容)
  • 新增輸入輸出方法:新增 java.lang.IO.*; 並提供 println(Object o)print(Object o)String readln(String prompt) 方法(Java 23),以及 println()String readln() 方法(Java 24 新增)

JEP 513:彈性建構式主體(預覽轉正式)

此功能從預覽階段轉為正式功能,其前身為 JEP 482JEP 492。本次沒有任何規格變更,因此下方延用前一版簡介

開發人員可以更自由地操作建構函式的行為,本功能允許一些特定的語句在明確的建構式呼叫(即 super(..)this(..))之前出現。因為它允許將判斷邏輯放在呼叫父類別的建構式之前,從而避免了將某些檢查和初始化邏輯分解到靜態方法和中間建構式中的必要。例如:如果建構式可以在呼叫父類別建構式之前先行驗證參數,那麼當參數無效時就能夠拋出異常並避免不必要的父類別實例化。

  • 提高可靠性:在呼叫父類別建構式或其他建構式之前檢查初始化欄位,確保衍生類別的狀態在父類別建構式執行時就已經準備就緒,以避免潛在的錯誤。尤其在方法覆寫的情況下,能確保子類別的欄位狀態在父類別方法執行前已經正確初始化
  • 程式碼更清晰:將欄位初始化邏輯集中在建構函式開頭,使程式碼結構更清晰,易於閱讀和維護

它讓 Java 建構式更加靈活,允許在調用其他建構式之前先初始化操作,從而提高程式碼的可靠性和可維護性。然而,開發人員在使用此功能時需要注意其潛在的複雜性和錯誤風險,並確保相容現有的程式碼。

函式庫

JEP 508:向量 API(第十次孵化)

此功能進入第十次孵化階段,其前身為 JEP 469JEP 489。本次為延續孵化階段,加入數項小變更但描述未變,因此下方延用前一版簡介

歷經了十次孵化,在 Java 25 中本功能仍未轉正。開發人員可以使用 Vector API 去描述和表示向量計算。在支援的 CPU 架構上,於運行時能夠可靠地編譯成最佳向量指令,從而實現優於等效標量計算的性能。預計這個 API 將持續孵化(最多只進行少量更改)直到來自 Project Valhalla 的必要功能(基於值的類別和物件)成為預覽功能為止。

  • 引入一個 API 來清晰簡潔地表達各種向量計算,包括在循環內組成的向量操作序列,可能還包括控制流
  • 平台獨立:API 應該獨立於 CPU 架構,並能夠在支援向量指令的多個架構上實現
  • 提供了一組類別和方法,用於建立、操作和訪問向量
  • 支援各種向量操作,例如:加減乘除、比較、邏輯運算等

JEP 505:結構化並行處理(第五次預覽)

此功能進入第五次預覽階段,其前身為 JEP 480JEP 499。本次為延續預覽階段並收集更多意見,少部分規格變更但描述未變,因此下方延用前一版簡介

結構化並行處理能讓開發者將一組相關任務(運行在不同執行緒上)視為單一的工作單元,從而簡化錯誤處理和取消操作、提升可靠性,並加強可觀察性。這個 API 提倡一種並行編程風格,可以消除因取消和關閉而產生的常見風險,如執行緒洩漏和取消延遲。

  • 簡化並行程式設計,特別是在使用虛擬執行緒時
  • 提供一種結構化、可預測且易於推理的並行程式模型
  • 引入 StructuredTaskScope 類別以允許開發者將一個任務發展成一組並行的子任務且同時能彼此協調:
    • fork() 方法:創建和啟動子任務,並返回子任務的結果
    • join() 方法:等待所有子任務完成,並處理任何異常
    • 支援自動取消子任務:如果父任務被取消,則所有子任務也會被自動取消
    • 確保子任務在其父任務完成之前完成,並集中處理異常
  • 支援範圍值(JEP 487 Scoped Values)的繼承:子任務可以繼承父任務的範圍值綁定,從而簡化資料共享

JEP 506:範圍值(預覽轉正式)

此功能從預覽階段轉為正式功能,其前身為 JEP 481JEP 487。本版僅微調一個方法的參數,因此下方延用前一版簡介

允許一個方法在執行緒內安全且有效率地與它的被調用者(無論是直接或間接調用)以及子執行緒共享不可變的資料。範圍值(Scoped values)比執行緒局部變數(thread-local variables)更容易理解,特別是和虛擬執行緒(JEP 444)和結構化並行處理(JEP 499)一起使用時。它們具有更低的空間和時間成本。

  • 引入 ScopedValue 類型,作為共享資料的容器
  • 提供 ScopedValue.where(key, value).run(op) 語句 ,將 ScopedValue 與特定值綁定,並在該綁定範圍內執行程式碼
  • 子執行緒可以繼承父執行緒的 ScopedValue 綁定

JEP 502:穩定值(首次預覽)

本功能引入的穩定值是一種持有不可變資料的物件,它被 JVM 視為常數,從而實現與宣告欄位為 final 時相同的效能最佳化。然而,與 final 欄位相比,穩定值在初始化時機方面提供了更大的靈活性。穩定值的核心目標包括:

  • 通過分解程式狀態的單體初始化來改善 Java 程式的啟動速度
  • 在不顯著地影響效能的情況下,將穩定值的創建與其初始化解耦
  • 保證穩定值最多只初始化一次,即使在多執行緒程式中也是
  • 用戶程式碼能夠安全地享受原先只有 JDK 內部程式碼才能使用的常數折疊最佳化

穩定值透過 StableValue 類型實現,它可以持有單一資料數值(也就是它的「內容」)。穩定值必須在首次獲取其內容前的某個時間點進行初始化,之後便不可變更。從使用角度來看,它彌補了 final 欄位與非 final 欄位之間的空白。

安全性

JEP 510:密鑰派生函數 API(預覽轉正式)

此功能從預覽階段轉為正式功能,其前身為 JEP 478。本次沒有任何規格變更,因此下方延用前一版簡介

引入密鑰派生函數(Key Derivation Functions、KDFs)的 API,它是一種用於從密鑰和其他數據派生出其他金鑰的密碼演算法,應用於加密和身份驗證。它有下列幾個重要的目標:

  • 讓程式能使用 KDF 演算法,例如:基於 HMAC 的提取和擴展金鑰衍生函數(HKDF,RFC 5869)和 Argon2(RFC 9106
  • 在金鑰封裝機制(Key Encapsulation Mechanism、KEM,JEP 452)的實現中、更高級別的協定(例如 TLS 1.3 中的混合金鑰交換)中、以及在密碼方案(例如混合公鑰加密(Hybrid Public Key Encryption、HPKE,RFC 9180)中,實現 KDF 的應用
  • 允許安全提供者用 Java 程式碼或原生程式碼實現 KDF 演算法
  • 包括 HKDF 的實現並引入其他特定於 HKDF 的 API

JEP 470:隱私增強郵件編碼的加密物件(首次預覽)

引入一組新的 API 將代表著「加密金鑰、證書和證書撤銷清單」的物件去編碼成廣泛使用的隱私增強郵件(PEM)傳輸格式,以及從該格式解碼回物件。

  • 易用性:定義一個簡潔的 API,用於在 PEM 文本和代表金鑰、證書及證書撤銷清單的對象之間進行轉換
  • 支持標準:支持 PEM 文本與具有二進制格式標準表示的加密對象之間的轉換,包括 PKCS#8(私鑰)、X.509(公鑰、證書和證書撤銷清單)和 PKCS#8 v2.0(加密私鑰和非對稱金鑰)

性能

JEP 521:分代型 Shenandoah 垃圾收集器(預覽轉正式)

此功能從預覽階段轉為正式功能,其前身為 JEP 404。本次沒有任何規格變更,因此下方延用前一版簡介

強化 Shenandoah (仙納度)垃圾收集器,使其擁有分代的收集能力,以提高可持續的吞吐量、負載高峰彈性和記憶體利用率。本功能的主要目標是提供分代模式,但不會影響未分代的 Shenandoah。未來的版本中預計將分代模式設為預設選項。

  • 降低持續性的記憶體占用,同時維持低 GC 停頓時間
  • 減少 CPU 使用率和耗電量
  • 提升系統對分配負載突增的應對能力
  • 維持高吞吐量

JEP 519:壓縮物件標頭 (預覽轉正式)

此功能從預覽階段轉為正式功能,其前身為 JEP 450。本次沒有任何規格變更,因此下方延用前一版簡介

本功能透過刪除物件標頭中的未使用空間和壓縮標頭資訊來減少物件記憶體佔用。它是一種新的記憶體布局,可以節省記憶體空間並提高效能。在 64 位元架構上,將 HotSpot JVM 中的物件標頭尺寸從 96 至 128 位元減少到 64 位元。這將減少堆積的大小並提高部署密度,增加資料局部性。

  • 將目標 64 位元平台(x64 和 AArch64)上的物件標頭尺寸減少到 64 位元(8 位元組)
  • 減少實際工作負載上的物件大小和記憶體佔用
  • 不會在目標 64 位元平台上產生超過 5% 的吞吐量或延遲開銷
  • 僅在極少數情況下,不會在非目標 64 位元平台上產生可測量的吞吐量或延遲開銷

JEP 514:預先編譯的指令列人因工程學

簡化建立預先編譯快取的流程,使開發者能夠輕鬆地利用這項能夠顯著提升應用程式啟動速度的功能。本提案引入了新的命令列選項 AOTCacheOutput,使得開發者能夠在單一步驟中完成訓練運行和 AOT 快取建立,同時不犧牲現有工作流程的表達能力。

  • 簡化工作流程:將原本需要兩個步驟的流程縮減為一個,大幅提升開發者生產力
  • 自動化臨時檔案管理:自動處理 AOT 設定檔的創建和清理,減少開發者的負擔
  • 保持向後相容性:不影響現有的兩步驟工作流程,開發者仍可選擇手動協調訓練和快取建立
  • 增強工具整合能力:簡化的流程更易於整合到自動化建置系統和持續集成流程中
  • 提升使用者體驗:降低使用 AOT 快取的門檻,鼓勵更多開發者利用這項效能優化功能

JEP 515:預先編譯的方法執行描述檔

讓上一次程式執行時的方法執行描述檔於 HotSpot JVM 啟動時立即可用,進而改善 Java 應用程式的暖機時間。這個方案巧妙地將描述檔收集的負擔從生產環境執行轉移到訓練執行階段,然後通過預先編譯快取將這些描述檔傳遞給後續的應用程式執行。

值得注意的是,即使有了快取的描述檔,HotSpot JVM 仍然會在應用程式執行時繼續收集新的描述檔資料並進行動態優化。這確保了即使應用程式的行為模式發生變化,JVM 也能夠適應並提供最佳效能。這種預先編譯描述檔與線上描述檔收集和 JIT 編譯的結合,為應用程式提供了更短的暖機期間和更快達到峰值效能的能力。

  • 更快的暖機時間:應用程式可以更快地達到峰值效能,因為 JIT 編譯器可以立即根據預先收集的描述檔進行優化,而不必等待收集足夠的執行資料
  • 改善啟動體驗:對於需要頻繁重啟的應用程式(如微服務、無伺服器函式等),啟動後能更快地處理請求,提供更一致的使用者體驗
  • 無需修改程式碼:開發者不需要對應用程式、函式庫或框架的程式碼進行任何更改,就能享受到效能提升
  • 資源使用效率提高:減少了在生產環境中收集描述檔的開銷,使得 CPU 和記憶體資源能更多地用於處理實際業務邏輯
  • 與現有工作流程整合:利用現有的預先編譯快取建立命令,不需要學習新的工作流程
  • 動態適應性保留:即使使用預先編譯描述檔,JVM 仍然會根據實際執行情況調整其優化策略,確保長期運行效能

內建工具

JEP 509:JDK 飛行紀錄器的 CPU 時間分析資訊(實驗性)

本功能的核心目標是增強 JDK Flight Recorder,讓它可以在 Linux 平台上捕獲更精確的 CPU 時間分析資訊。功能實現是使用了 Linux 核心自 2.6.12 版本以來提供的精確測量 CPU 週期消耗的能力。它與現有的執行採樣器不同,新的 CPU 時間分析功能以固定的 CPU 時間間隔(而非固定的實際經過時間間隔)發出信號,這使得分析結果能更準確地反映實際的 CPU 使用情況。

具體而言,它引入了兩個新的 JFR 事件:

  • jdk.CPUTimeSample:記錄特定堆疊追蹤的 CPU 時間樣本,包含開始時間、被採樣執行緒識別、堆疊追蹤、採樣週期等資訊
  • jdk.CPUTimeSamplesLost:在因實作限制而丟失樣本時觸發,記錄上一輪採樣中丟棄的樣本數量,確保事件流整體上能正確反映程式的 CPU 活動情況

這些事件的採樣率可以透過 throttle 屬性設定,既可以設定為時間週期(如每 10ms 一次),也可以設定為整體速率(如每秒 500 次)。預設設定為每秒 500 次採樣,而在 JDK 內建的分析配置中則為每 10ms 一次。較高的採樣率能提供更精確的分析結果,但會增加程式的採樣開銷。

JEP 518:JDK 飛行紀錄器的協作式採樣

本功能的 JFR 協作式採樣機制徹底重新設計了採樣方法,提升了 JFR 在非同步採樣執行緒堆疊時的穩定性,並同時盡可能減少安全點偏差的影響。其核心思想是:只在安全點解析執行緒堆疊,但透過協作式的方式來減輕安全點偏差問題。

這種協作式採樣方法帶來了以下優點:

  • 顯著提升穩定性:由於堆疊解析只在安全點進行,避免了原本不可靠的啟發式方法,大幅降低了 JVM 崩潰的風險
  • 採樣效率提高:創建採樣請求所需的工作量極小,可以在硬體事件回應中或信號處理程序內完成,減輕了採樣執行緒的負擔
  • 程式碼簡化:在安全點進行堆疊解析和事件發出的程式碼更為簡單,甚至可以在目標執行緒上動態分配記憶體
  • 可擴展性增強:由於採樣執行緒不再需要運行複雜的啟發式方法,其工作量大幅減少,所以提高了整體可擴展性

JEP 520:JDK 飛行紀錄器的方法計時與追蹤

本功能使用位元組碼插樁(bytecode instrumentation)擴展了 JFR,以提供方法計時和追蹤功能。該功能引入了兩個新的 JFR 事件:jdk.MethodTimingjdk.MethodTrace,它們都接受一個過濾器來選擇要計時和追蹤的方法。

以下是 JFR 方法計時與追蹤功能的主要優點:

  • 精確性:與基於抽樣的分析器不同,JFR 方法計時與追蹤可以記錄方法調用的完整且精確的統計數據,而非不完整且不精確的抽樣統計數據
  • 無侵入性:開發者可以在不修改原始碼的情況下,對特定方法進行計時和追蹤,非常適合分析第三方函式庫或 JDK 本身的類別
  • 多重配置方式:可以透過命令列參數、配置檔案、jcmd 工具,以及使用 JMX 透過網路進行配置,提供了極大的靈活性
  • 註解支援:可以透過指定註解來選擇要計時或追蹤的方法,這使得在大型程式碼庫中標記和分析特定方法變得更加容易
  • 與其他 JFR 事件整合:產生的 MethodTimingMethodTrace 事件可以與 JFR 發出的其他事件(如鎖競爭、方法抽樣或 I/O 的事件)相關聯,提供更全面的效能分析視角

管理工作

JEP 503:移除 32 位元的 x86 平台

此功能已在 JEP 501 中棄用,並在本版中移除

移除 32 位元 x86 架構的原始碼和構建支援。此架構已在 JDK 24(JEP 501)中被標記為棄用,並明確計畫在未來版本中完全移除。

  • 解除對需要平台特定支援的新功能實作 32 位元 x86 備用方案的限制
  • 移除所有僅適用於 32 位元 x86 的程式碼路徑
  • 簡化 JDK 的構建和測試基礎設施

總結

Java 25 作為 Java 語言 30 週年的獻禮,既繼承了穩定可靠的傳統,又帶來了眾多實用的創新。從語言層面的簡化入門到底層的效能優化,再到監測與安全能力的增強,這個版本全方位提升了 Java 的開發體驗。

對於初學者來說,精簡原始檔和實例主方法、模組匯入宣告等功能大幅降低了學習門檻;對於專業開發者,彈性建構式主體、範圍值、分代型 Shenandoah 垃圾收集器等功能則提供了更強大的工具和更高的效能。JDK 飛行紀錄器的三項增強功能也為性能調優和問題診斷提供了更精確、更穩定的支援。

展望未來,Java 25 作為長期支援版本,將成為許多企業未來數年的技術基礎。它不僅是一個 30 週年的里程碑,更是 Java 生態系統持續創新與演進的見證。隨著基礎型別模式匹配、向量 API 等預覽功能的不斷成熟,Java 開發體驗還將持續進步,在下一個 30 年繼續為軟體開發帶來更多可能性。

本篇文章的內容為老喬原創、二創或翻譯而來。雖已善盡校對、順稿與查核義務,但人非聖賢,多少仍會有疏漏之處難以避免。如果大家有任何問題、建議或指教,都歡迎在底下留言與老喬討論!

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

one + three =

目錄
返回頂端