JDK 8~26 核心特性一览:从 Stream 到 Scoped Values
特性介绍
JDK 的变化不只有语法变短。集合处理、异步编排、类型表达、线程模型和运行时都在演进。先把常用能力放回版本地图,再决定从哪一项开始学,会比按 JEP 编号逐条阅读更容易上手。
本文覆盖 JDK 8~26 的代表性变化,不是全部发布说明,也不是版本升级建议。示例统一使用 JDK 21 运行,代码旁单独说明能力首次正式提供的版本。
常用正式特性地图
| 版本 | 代表能力 | 可以用来做什么 |
|---|---|---|
| 8 | Lambda、Stream、Optional、java.time、CompletableFuture | 集合、时间和异步处理 |
| 9 | 模块系统、集合工厂、JShell | 模块边界、简洁集合、交互实验 |
| 10 | 局部变量 var | 根据初始化表达式推断局部类型 |
| 11 | HTTP Client | 原生同步与异步 HTTP 请求 |
| 14 | switch 表达式 | 分支直接产生结果 |
| 15 | 文本块 | 多行 SQL、JSON、文本 |
| 16 | record、instanceof 类型模式 | 数据载体与类型检查 |
| 17 | sealed 类型 | 限定允许的直接子类型 |
| 21 | 虚拟线程、有序集合、record/switch 模式 | 并发等待、首尾操作、数据匹配 |
| 22 | 未命名变量/模式、FFM API | 忽略无用绑定、外部函数与内存 |
| 25 | Scoped Values、模块导入、紧凑源文件 | 有界上下文、导入与入门程序 |
| 26 | HTTP/3 支持等 | 网络能力及运行时继续演进 |
语言特性的正式版本可查 Java 语言变化表。HTTP/3 属于26,不应写进"JDK11原生HTTP客户端已经支持"的代码说明。
12、13、18、19、20、23、24 没有单独列在这张常用正式特性表里,不代表它们没有更新。很多今天常用的特性正是在这些版本里预览、孵化和完善。
基本用法
用版本读懂一小段代码
下面把几种常用能力放在一个程序中。代码短不意味着它只能在最早的版本运行:最低版本由全部使用能力中要求最高的一项决定。
java
import java.util.*;
public class JdkFeatureMap {
// record:JDK 16 正式提供
record Order(String id, int amount) {}
public static void main(String[] args) {
// List.of:JDK 9
// var:JDK 10
var orders = List.of(
new Order("A", 100),
new Order("B", 200));
// Stream:JDK 8;这里使用的 toList:JDK 16
List<String> ids = orders.stream()
.filter(order -> order.amount() >= 100)
.map(Order::id)
.toList();
System.out.println(ids);
// [A, B]
// switch 表达式:JDK 14
String label = switch (ids.size()) {
case 0 -> "无订单";
case 1 -> "单笔";
default -> "多笔";
};
System.out.println(label);
// 多笔
}
}
保存为 JdkFeatureMap.java,使用 JDK 21 编译运行。这一整段至少需要16,不能因为 Stream 出现在8,就把整段标成"JDK8代码"。
var 仍有静态类型,不能随意换成别的类型;record 仍是对象,不会让数组和列表自动深层不可变;toList 也不等于 JDK 8 的 Collectors.toList。学习特性时要连同 API 契约一起看。
中间版本在做什么
| 版本 | 代表变化及状态 |
|---|---|
| 12 | switch 表达式首次预览 |
| 13 | 文本块首次预览,动态 CDS 等运行时更新 |
| 18 | 默认字符集改为 UTF-8等更新 |
| 19 | 虚拟线程预览,record 模式预览 |
| 20 | 上述能力继续预览;Scoped Values 孵化 |
| 23 | 分代 ZGC 成为默认;字符串模板不再保留此前预览 |
| 24 | 非分代 ZGC 移除;改进 synchronized 场景的虚拟线程 pinning |
这张表用来解释演进路线,不是每个版本只有这一项变化。尤其不能把首次预览当作首次正式发布,也不能认为经过预览的 API 一定会以相同形态保留。
版本22的字符串模板仍是预览,之后撤回;25的 ScopedValue 已正式,但 StructuredTaskScope 仍需按预览能力处理。版本26也继续有预览特性,例如基本类型模式等,不应与正式 API 混写。JDK 迁移指南中的版本变化
实际应用
按日常任务选择学习入口
如果主要写数据处理,先学 Stream 的收集与分组、Optional 的返回值组合、java.time 的类型与时区。它们会反复出现在业务方法里。
如果对象定义和分支很多,按 switch 表达式、instanceof 模式、record、sealed、switch/record 模式的顺序阅读。先知道对象怎样定义,再看怎样匹配,比一开始嵌套多个新语法更容易理解。
如果主要处理并发调用,先把 CompletableFuture 的依赖关系和执行器讲清,再看虚拟线程的同步式编程模型。两者不是简单的新旧替代:一个重在阶段组合,一个改变等待任务的线程成本。
HTTP Client 与 Sequenced Collections 可以独立阅读。G1/ZGC 则属于运行时专题,主要通过参数、日志和测量认识,不应期待一段业务代码就看出性能差异。
先看环境,再复制示例
运行 JDK、编译目标和框架兼容是三个维度。编译器支持某种语法,不表示部署机器能加载对应 class 文件;把 --release 设低,也不会把新语法自动翻译成旧版本写法。
本系列每篇写实际运行环境的大版本。没有对应运行环境的实验会明确标记未验证,不把文档核对等同运行测试。
LTS 是发行与支持策略,不是一个功能开关。8、11、17、21、25 常作为 LTS 版本讨论,但具体维护期限、许可证和支持来源要看所用发行版。不要仅凭"LTS"推断某个商业组件已经兼容,也不把26写成 LTS。
本系列保留8~26的规划范围,不将它包装成永远有效的"最新版本大全"。阅读较新资料时,仍需回到目标版本文档核对。
总结
版本地图的用途是定位能力:数据处理看8,语言表达重点看14~17和21,并发等待看21,上下文范围看25。正式版、预览版和实际运行环境分开说明,才不会把几个正确片段拼成一段跑不起来的程序。
如果这篇文章对您有用,欢迎关注。后续会继续拆解 Java 后端的实用代码,讲清写法、原理和使用时要注意的细节。