Java 是用於後端服務、企業系統與桌面程式的程式語言;JDK 則提供編譯器、執行環境與開發工具。從 Java 8 到 25,語言加入 Lambda、record、pattern matching,執行平台也加入 virtual threads。選版本時除了新功能,還要一起確認框架相容性、JDK 發行版與維護期限。

以下以 Java 8、11、17、21、25 五個 LTS 為主軸比較,並補充 Java 26 的非 LTS 功能。版本與支援資訊核對至 2026 年 9 月 8 日;尚未釋出的版本只列官方規劃,不把 preview 功能視為已確定納入下一個 LTS。

Java 與 LTS 是什麼

LTS 是 Long-Term Support,意指發行商為特定 Java 版本提供較長的維護週期。Java 採每六個月一次的功能版本節奏,非 LTS 的更新窗口通常較短;LTS 則方便長期服務安排升級,但具體期限與支援內容由各家發行商決定,不能只憑 LTS 標籤判斷。

Oracle JDK、Eclipse Temurin、Amazon Corretto 都是可取得的 JDK 發行版,但授權與支援方案不同。各名稱的關係可參考 JDK、JRE、JVM 與 OpenJDK 發行版選擇;選擇免費更新或商業支援時,須查看實際使用的發行版與更新版本。

Java 17、21、25 分別於 2021、2023、2025 年 9 月釋出,間隔兩年。Oracle 的下一個預定 LTS 是 Java 29,時間為 2027 年 9 月;Java 27 列為 2026 年 9 月的非 LTS 版本。每年兩次功能版本更新,因此兩年間版本號會增加 4。

以下分開列出 Oracle 商業支援期限、Temurin 社群二進位檔提供期限與 Corretto 維護終止時間。這些欄位不是同一種付費服務,Temurin 的「至少」日期也不是保證當天停止提供:

LTSGA 時間Oracle Premier 商業支援Oracle Extended 商業支援Temurin 至少提供至Corretto EOL
82014-032022-03(已結束)2030-122030-122030-12
112018-092023-09(已結束)2032-012027-102032-01
172021-092026-092029-092027-102029-10
212023-092028-092031-092029-122030-10
252025-09-162030-092033-092031-092032-10

Oracle 的支援期限不等於免費授權期限。Oracle JDK 17 自 2024 年 10 月起的新更新已改用 OTN;Oracle JDK 21 在 2026 年 9 月後釋出的更新也預定改用 OTN,25 目前採 NFTC。應依所下載版本的授權判斷用途,不能推論先前以 NFTC 取得的版本會在同一天自動變成付費。Temurin 與 Corretto 提供免費 OpenJDK 發行版,商業 SLA 另依供應商方案。

Java 版本怎麼選

截至本次核對,Java 25 是最新 LTS,Java 26 是已釋出的非 LTS 版本。選擇可先依專案限制縮小範圍,再看後面的語言功能範例。

情境優先評估確認事項
新專案Java 25 LTS框架、建置工具、部署平台與監控代理是否支援
已使用 Java 21持續更新 21,另評估 25是否需要 gatherers、較新的虛擬執行緒實作與較長維護期
Java 8/11 舊系統以 21 或 25 為目標,必要時分階段遷移相依套件、反射、移除的 API 與測試成本
試用最新功能Java 26 非 LTS可否配合短更新週期,以及功能是否仍需 –enable-preview

Java 8 — 一切的起點

Java 8 於 2014 年釋出,為後續 Java 開發方式帶來多項重要變化:

  • Lambda 表達式:把過去一坨 anonymous inner class 折成一行
  • Stream API:宣告式的集合運算,可串接、可平行化
  • java.time 套件:取代難用的 DateCalendar,詳細介紹寫過 Java 8 的日期時間 API 介紹與各種常見操作範例
  • Optional:讓「可能沒有值」這件事被型別系統表達出來
  • interface default methods:介面可以帶實作,後續才可能進化 Stream API

下面這段是最經典的 Lambda + Stream 範例,從 Java 8 開始到 25 都可以這樣寫:

// 從一串名字裡找出長度大於 3 的,全部轉大寫,排序後印出
List<String> names = java.util.Arrays.asList("ada", "kyle", "tom", "alice");
names.stream()
     .filter(n -> n.length() > 3)   // Lambda
     .map(String::toUpperCase)       // method reference
     .sorted()
     .forEach(System.out::println);  // ALICE, KYLE

Java 8 為什麼黏住這麼久?除了功能本身夠用,企業系統的相依鏈、Spring 4 / 5 的長尾、Android 一度只支援部分 Java 8 功能,都讓升級動機被稀釋。Oracle Premier Support 雖然在 2022-03 結束,但 Eclipse Temurin、Amazon Corretto 還會免費維護到 2030-12,所以舊系統要繼續吃 Java 8 安全更新,技術上沒問題。

Java 11 — 吸收 9、10 的整理期

Java 11 是 Java 8 之後第一個 LTS,等於把 9、10 兩個短週期版本累積的功能一次給長期維護。

Java 11 自身的重點

  • JEP 321 標準化 HTTP Client:之前在 incubator 階段,11 終於進入 java.net.http 正式套件,支援 HTTP/2 與 async
  • 移除 Java EE 與 CORBA 模組(這些 API 已過時)
  • ZGC 實驗性首次登場
  • 單檔 launch:java HelloWorld.java 不用先編譯就能跑,寫 script 方便很多
  • TLS 1.3

吸收 Java 9(2017-09)

  • JEP 261 模組系統(Project Jigsaw):JDK 本身被切成模組,大型應用也能用 module-info.java 宣告依賴
  • JShell:官方 REPL,學習與測試 API 很方便
  • List.of()、Map.of() 等 immutable factory:跟以前 Arrays.asList() 的差別寫過 Java 的 Arrays.asList() 與 List.of() 差別
  • G1 設為預設 GC

吸收 Java 10(2018-03)

  • JEP 286 var 區域變數型別推斷:寫起來像 var list = new ArrayList<String>();,少打幾個字
  • G1 並行 full GC

不過 Java 11 的吸收成績只能算半成功。模組系統雖然強大,業界吸收速度卻很慢,許多框架(Spring、Hibernate)為了向下相容並沒有完全模組化,結果開發者升上 11 之後常常被 reflection、JDK 內部 API 的存取限制咬到。Oracle Premier Support 已在 2023-09 結束,但 Corretto 免費維護到 2032-01,繼續用 Java 11 還是夠安全。

Java 17 — 吸收 12-16,現代 Java 成型

Java 17 是「現代 Java」的雛形成型版本,把 12 到 16 累積的 preview 功能大量轉正。

Java 17 自身的重點

  • JEP 409 sealed classes:限制誰可以繼承一個 class,配合 pattern matching 是 ADT(algebraic data type)的基礎。詳細寫過 Java 17 新增的 sealed、non-sealed class 與 final class 差別
  • JEP 403 強封裝 JDK 內部 APIsun.*com.sun.* 之類的內部 API 預設禁止反射存取,這個改動讓很多舊 library 升級時直接爆炸
  • Enhanced Pseudo-Random Number Generators
  • 新 macOS 渲染 pipeline(Apple Silicon 友善)

吸收 Java 12-16 的關鍵正式功能

到 Java 17,現代 Java 的字典裡多了 sealed、record、pattern matching、text blocks、switch expression,整個語法樣貌跟 Java 8 已經是兩個世代的東西。底下這段示範 switch expression 的寫法:

// switch 當運算式用,可以直接 return 結果
String role = switch (level) {
    case 1, 2     -> "junior";          // 多 case 合併
    case 3, 4, 5  -> "mid";
    case 6, 7     -> "senior";
    default       -> throw new IllegalArgumentException("unknown level: " + level);
};

另外 Java 15 正式的 text blocks 也是 17 帶進主流的關鍵語法,寫 SQL、JSON、HTML 終於不用一堆字串拼接:

// 三引號開頭,內部排版照原樣保留,縮排會自動以最少縮排為基準對齊
String json = """
        {
          "name": "kyle",
          "role": "engineer",
          "skills": ["Java", "Spring", "Linux"]
        }
        """;

// 寫 SQL 也乾淨多了
String sql = """
        SELECT id, name, created_at
        FROM users
        WHERE status = 'active'
          AND created_at > ?
        ORDER BY created_at DESC
        """;

支援狀態:Oracle Premier 到 2026-09,Eclipse Temurin 到 2027-10,Corretto 到 2029-10。

Java 21 — 吸收 18-20,virtual threads 元年

Java 21 是這幾年最重磅的一版,整整 15 個 JEP,其中最值得記住的是 virtual threads 終於從 preview 走到正式。

Java 21 自身的重點

  • JEP 444 virtual threads 正式:對高併發 IO 服務(HTTP backend、資料庫互動)是劃時代改變,過去要靠 reactive programming 才能擠出的吞吐量,現在用同步寫法就達得到
  • JEP 431 sequenced collections:替 List、Deque、LinkedHashSet 等補上統一的 getFirst()getLast()reversed() 介面
  • JEP 441 pattern matching for switch 正式:switch 可以對型別、record 結構做匹配
  • JEP 440 record patterns 正式:可以直接拆解 record 的欄位
  • generational ZGC:ZGC 加上世代分區,提升吞吐
  • KEM API:為後量子加密鋪路

吸收 Java 18-20

  • 18JEP 400 預設字元集改為 UTF-8。這是個容易被忽略卻影響甚大的改動,過去 new FileWriter("a.txt") 在不同平台、不同 locale 會用不同編碼,從 18 開始終於統一;同版還有簡易 web server(jwebserver
  • 19:virtual threads 第一輪 preview、structured concurrency 進孵化
  • 20:scoped values 進孵化、virtual threads 第二輪 preview

下面示範 virtual threads 的寫法。它適合包含大量等待的並行 I/O 任務;可承載的任務數仍受記憶體、連線池與下游服務容量限制。

// 用 virtual thread executor,跑一萬個並發 IO 任務
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    IntStream.range(0, 10_000).forEach(i -> {
        executor.submit(() -> {
            // 模擬 IO,例如打 HTTP 或讀資料庫
            Thread.sleep(Duration.ofSeconds(1));
            return i;
        });
    });
}  // executor 自動 close,等所有任務完成

若為每個任務建立一條 platform thread,會增加作業系統執行緒與 stack 的成本。Virtual thread 在等待支援的阻塞操作時通常能釋放 carrier thread,適合保留同步程式寫法;它不會讓 CPU 密集運算自動變快,也不代表可以無限制增加並行數。

JEP 441 把 pattern matching 帶進 switch,配合 sealed class 與 record 就能寫出真正的 ADT 風格判斷,再也不用層層 if-else 加 instanceof 強制轉型:

// 一個密封繼承樹(sealed),所有 Shape 子類都列舉出來
sealed interface Shape permits Circle, Square, Triangle {}
record Circle(double radius) implements Shape {}
record Square(double side) implements Shape {}
record Triangle(double base, double height) implements Shape {}

// switch 直接對型別匹配,編譯器會檢查是否窮舉所有 case
double area = switch (shape) {
    case Circle c   -> Math.PI * c.radius() * c.radius();
    case Square s   -> s.side() * s.side();
    case Triangle t -> 0.5 * t.base() * t.height();
    // 不需要 default:sealed + 全部窮舉,編譯器幫忙保證
};

JEP 440 record patterns 更進一步,把 record 的欄位直接拆解出來,省掉一大堆 getter 呼叫:

record Point(int x, int y) {}
record Line(Point from, Point to) {}

// 直接在 switch case 裡解構 record,連嵌套的 record 也能拆
String describe = switch (obj) {
    case Point(int x, int y)                       -> "點 (" + x + "," + y + ")";
    case Line(Point(var x1, var y1),
              Point(var x2, var y2))               -> "線段 " + x1 + "," + y1 + " → " + x2 + "," + y2;
    case null                                      -> "空值";
    default                                        -> "未知形狀";
};

Java 21 於 2023 年 9 月釋出,與 2025 年 9 月的 Java 25 相隔兩年。Oracle Premier Support 列至 2028 年 9 月,Temurin 則至少提供至 2029 年 12 月;實際採用時仍應持續安裝所選發行版的更新。

Java 25 — 吸收 22-24,目前最新 LTS

Java 25 在 2025 年 9 月 GA,是寫這篇文章時最新的 LTS。共 18 個 JEP,重點是把 21 之後兩年累積的功能轉正、補完幾個老問題。

Java 25 自身的重點

  • JEP 512 compact source files & instance main:寫 void main() 就能執行,不用 public static void main(String[] args) 那一坨樣板。給新手教學跟一次性 script 用
  • JEP 513 flexible constructor bodies:建構子可以在 super() 之前做事(驗證參數、預處理),不再受限於必須第一行就呼叫父類別建構子
  • JEP 519 compact object headers:在支援的平台以較小的物件標頭降低記憶體需求;Java 25 將此功能轉為正式,並非所有情境都會自動啟用或獲得相同效益
  • JEP 510 KDF APIJEP 509 JFR CPU-time profiling
  • module import declarationsPEM API(preview)generational Shenandoah 正式
  • 移除 32-bit x86 支援

吸收 Java 22-24

  • 22JEP 454 FFM API 正式(Foreign Function & Memory,取代 JNI 的現代外部函數呼叫)、unnamed patterns 正式、stream gatherers 進 preview、多檔 source launch
  • 23:ZGC 預設改為 generational、Markdown Javadoc
  • 24JEP 485 stream gatherers 正式(Stream API 自 Java 8 之後最大擴充,可以自訂中間操作)、JEP 484 Class-File API 正式、JEP 483 AOT class loading、永久關閉 Security Manager、ML-KEM / ML-DSA 後量子加密、JEP 491 virtual thread synchronization without pinning(補上 21 virtual thread 在 synchronized 區塊內會 pin 住底層 carrier thread 的最大坑)

下面是 Java 25 的 instance main 寫法,以及 Java 24 開始正式的 stream gatherers 範例:

// JEP 512 compact source files:以下兩種 main 寫法擇一,存成 Hello.java
// 不需要宣告 class、不需要 public static void main、不需要 import
void main() {
    IO.println("Hello from Java 25");  // java.lang.IO 提供輸出方法
}

// 也可以收命令列參數,沒用到就不必宣告
void main(String[] args) {
    IO.println("收到參數數量:" + args.length);
}

JEP 512 真正的價值不在「少打字」,而在於降低 Java 入門門檻——教學第一堂課終於不用解釋什麼是 public、什麼是 static、什麼是 String[] args,可以直接寫邏輯。對寫一次性 script 的人也很方便,java Hello.java 直接跑。

另一個值得試的是 Java 24 起正式的 stream gatherers,這是 Stream API 自 Java 8 之後最大擴充,可以自訂中間操作(之前只能組合內建的 filter/map/flatMap 等):

import static java.util.stream.Gatherers.windowSliding;
import static java.util.stream.Gatherers.windowFixed;

// 滑動視窗:每次取連續 N 個元素,視窗每次往後移一格
var pairs = Stream.of(1, 2, 3, 4, 5)
    .gather(windowSliding(2))
    .toList();
// [[1,2], [2,3], [3,4], [4,5]]

// 固定視窗:分塊不重疊,常用於 batch 處理
var batches = Stream.of(1, 2, 3, 4, 5, 6, 7)
    .gather(windowFixed(3))
    .toList();
// [[1,2,3], [4,5,6], [7]]

Java 25 納入 Java 24 的 JEP 491,改善在 synchronized 中阻塞時的 virtual thread pinning;這不代表所有 native 呼叫情境都不會 pin。它也包含 stream gatherers,並將 compact object headers 轉為正式功能。Oracle Premier Support 列至 2030 年 9 月,Temurin 至少提供至 2031 年 9 月,Corretto EOL 為 2032 年 10 月。

番外:Java 26 — 非 LTS 但目前最新

Java 26 在 2026 年 3 月 17 日 GA,屬於非 LTS。以下分別標示正式、preview 與 incubator 功能;preview 是否會在下一個 LTS 定案,要依各 JEP 後續進度判斷。更多跨版本整理可參考 Java 25、26、27 新功能比較

  • JEP 517 HTTP/3 for HTTP Client(正式):Java 11 標準化的 HTTP Client 終於支援 HTTP/3 與 QUIC,網路 stack 跟上現代瀏覽器
  • JEP 516 AOT object caching with any GC(正式):Project Leyden 的成果延伸,啟動速度持續優化
  • JEP 522 G1 GC throughput improvement(正式):減少 G1 同步開銷,對既有用 G1 的服務是免費效能升級
  • JEP 504 移除 Applet API(正式)java.applet 終於進墳墓
  • JEP 500 Prepare to Make Final Mean Final:收緊 reflection 修改 final 欄位的漏洞,是後續真正鎖死 final 的鋪路
  • JEP 525 Structured Concurrency 第 6 輪 preview:從 21 開始 preview 至今還沒轉正,是 Loom 後續最重要的併發 API
  • JEP 530 Primitive types in patterns 第 4 輪 preview
  • JEP 529 Vector API 第 11 輪 incubator:仍在孵化

Java 26 沒有戲劇性的新功能,主要是把 25 沒收完的 preview 繼續推進,加上 HTTP/3、G1 同步優化等實用補完。生產環境繼續用 25 LTS 是最保險的選擇,不過 HTTP/3 client 是值得單獨拿來玩的東西。

該升級嗎?該升到哪一版?

還停在 Java 8 的場景其實非常多——金融系統、舊 Spring 服務、Android 老專案、JVM 上的 Scala 2 / Kotlin 1 應用,這些不見得要立刻動。Java 8 在 Eclipse Temurin、Amazon Corretto 上還會免費維護到 2030-12,安全更新有保障。但如果業務上開始想要 virtual threads、record、pattern matching 這些東西,那就值得排升級時程。

升級可優先以 Java 21 或 25 為目標,減少短期內再次遷移的需求;若舊框架或工具只支援 11、17,分階段升級仍有必要。先列出套件、建置工具、部署映像與監控代理的支援矩陣,再安排測試,不能只依 JDK 版本號決定一次跨越所有版本。

  • 跳 Java 21:穩定性已經夠成熟(GA 兩年多),virtual threads 對 IO 密集服務直接受益,仍須核對實際 Spring Boot 3 小版本的支援範圍
  • 跳 Java 25:改善在 synchronized 中阻塞時的 virtual thread pinning(JEP 491)、stream gatherers 對資料處理寫法更乾淨、compact object headers 省記憶體。新專案在相依工具支援時優先評估 25

框架相容性須看具體版本。Spring Boot 官方目前的 4.1.1 系統需求仍是 至少 Java 17,支援至 Java 26;不能把「Spring Boot 4」直接等同於「最低 Java 21」。第三方整合套件可能有額外條件,詳見 Spring Boot 系統需求

Java 8 到 25 的演進讓物件導向、函數式集合操作、模式比對與並行 API 能搭配使用。版本選擇的重點是所需功能、相依工具與更新來源能否同時滿足維護需求;下一個預定 LTS 為 Java 29,不預先保證目前的 preview 會在該版轉正。

常見問答

以下整理版本支援、升級與功能差異的常見問題。

LTS 是誰定的?非 LTS 的版本能用嗎?

LTS 是 Oracle 在 2018 年宣佈的策略,OpenJDK 社群與主流發行版(Temurin、Corretto、Zulu)跟進。非 LTS 版本(例如 22、23、24、26)只有六個月安全更新,適合愛嘗鮮、生命週期短的專案,不適合長期維護的服務。但拿來開發、實驗、寫 demo 完全沒問題。

用免費的 OpenJDK 跟 Oracle JDK 有什麼差別?

多數標準 Java 程式可在通過相容性驗證的 JDK 發行版上執行,但更新供應、授權與商業支援不同。Oracle JDK 不能概括成一律付費或一律免費,應核對所用更新版的授權及用途;Temurin、Corretto 等提供免費 OpenJDK 二進位檔。更完整的選擇方式可參考 JDK 發行版比較

升級會踩什麼坑?

  • Java 8 → 11:模組系統(JPMS)讓很多 reflection、JDK 內部 API 被擋住,舊 library 直接壞
  • Java 11 → 17:JEP 403 強封裝 JDK 內部 API,更多反射程式爆炸;要記得加 --add-opens 或升級到對 17 友善的 library 版本
  • Java 17 → 21:相對平順,只要原本沒亂用 deprecated API
  • Java 21 → 25:注意 32-bit x86 支援移除、Security Manager 永久關閉、移除幾個冷門 API

virtual threads 是不是 Java 21 推出來的?

Virtual threads 在 Java 19 開始 preview,Java 21 正式定案。Java 24 的 JEP 491 改善 synchronized 中的 pinning,Java 25 也包含此改進;不能把 JEP 491 的首次釋出版本寫成 25。它主要改善大量等待的 I/O 工作,效益仍要依程式與下游資源評估。

Java 21 跟 25 該選哪個?

新專案在相依工具支援時優先評估 25。既有 Java 21 專案可依相依套件支援、回歸測試及維護計畫評估升級,不必只按發佈後經過幾個月決定。25 的免費維護期更長(Corretto 到 2032-10),長期看比 21 划算。

JDK 內建的 HTTP Client 真的能取代 OkHttp、Apache HttpClient 嗎?

Java 11 標準化的 HTTP Client(JEP 321)支援 HTTP/2、async、reactive,到 Java 26 還補上 HTTP/3,日常 REST 呼叫絕對夠用。但生態系成熟度(攔截器、metrics、retry policy、認證套件)目前還是 OkHttp、Apache 領先,做複雜整合時可能還是會回去用第三方。

LTS 改為 2 年是好是壞?

兩年一次 LTS 讓新功能更常進入長期維護版本,但團隊仍可依所選發行版的期限安排升級,不必每次 LTS 都立即跟進。Preview 的定案速度也不等於 LTS 間隔,例如 virtual threads 從 Java 19 的 2022 年 9 月到 Java 21 的 2023 年 9 月約一年。

參考來源


Sponsored Links