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 的「至少」日期也不是保證當天停止提供:
| LTS | GA 時間 | Oracle Premier 商業支援 | Oracle Extended 商業支援 | Temurin 至少提供至 | Corretto EOL |
|---|---|---|---|---|---|
| 8 | 2014-03 | 2022-03(已結束) | 2030-12 | 2030-12 | 2030-12 |
| 11 | 2018-09 | 2023-09(已結束) | 2032-01 | 2027-10 | 2032-01 |
| 17 | 2021-09 | 2026-09 | 2029-09 | 2027-10 | 2029-10 |
| 21 | 2023-09 | 2028-09 | 2031-09 | 2029-12 | 2030-10 |
| 25 | 2025-09-16 | 2030-09 | 2033-09 | 2031-09 | 2032-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 套件:取代難用的
Date、Calendar,詳細介紹寫過 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 內部 API:
sun.*、com.sun.*之類的內部 API 預設禁止反射存取,這個改動讓很多舊 library 升級時直接爆炸 - Enhanced Pseudo-Random Number Generators
- 新 macOS 渲染 pipeline(Apple Silicon 友善)
吸收 Java 12-16 的關鍵正式功能
- 14:JEP 361 switch expressions 正式,switch 終於可以當運算式用、可以 yield 值。switch 的整段演進另外寫過 從 Java 7、17、21、25 到 Java 26,Java Switch 關鍵字的演變 。同版還加入 helpful NullPointerExceptions(NPE 訊息會直接告訴是哪個變數 null)
- 15:text blocks 正式,三引號多行字串;ZGC、Shenandoah 都從實驗轉正式
- 16:JEP 395 records 正式,一行宣告 immutable data class,跟 Lombok 的取捨寫過 Java 16 新增的 record 教學,與 lombok 和 POJO 的比較 ;同版還有 JEP 394 pattern matching for instanceof 正式、Unix-domain sockets
到 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
- 18:JEP 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 API、JEP 509 JFR CPU-time profiling
- module import declarations、PEM API(preview)、generational Shenandoah 正式
- 移除 32-bit x86 支援
吸收 Java 22-24
- 22:JEP 454 FFM API 正式(Foreign Function & Memory,取代 JNI 的現代外部函數呼叫)、unnamed patterns 正式、stream gatherers 進 preview、多檔 source launch
- 23:ZGC 預設改為 generational、Markdown Javadoc
- 24:JEP 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 月約一年。
參考來源
- Oracle: Oracle Java SE Support Roadmap (Java 支援與授權時程)
- Adoptium: Temurin™ Support (Temurin 更新與支援)
- AWS: Amazon Corretto FAQs (Corretto 維護期限)
- Spring: System Requirements (Spring Boot 系統需求)
- OpenJDK: JDK 25 (Java 25 功能清單)
- OpenJDK: JDK 26 (Java 26 功能清單)