§2.1.8 JDK LTS版本新特性(8 / 11 / 17 / 21)
考察意图:是否跟得上Java生态演进,知道每个LTS版本的关键变化和升级价值。
回答样板:
Oracle 2017年宣布6个月发布周期(3月/9月),每2年一个LTS(长期支持版本)。截至目前四个主要LTS:
JDK 8(2014.03)——革命性版本,目前仍有海量存量:
| 特性 | 说明 | 实际价值 |
|---|---|---|
| Lambda + Stream API | 函数式编程,集合操作的声明式写法 | Java 8的核心卖点,改变了Java编程范式 |
| Optional类 | 优雅处理null,避免NPE | 链式调用,配合orElse/orElseGet兜底 |
| 新的日期时间API | java.time包(LocalDate/LocalDateTime/Instant) | 线程安全+不可变对象,替代joda-time |
| 接口默认方法 | default关键字,接口可提供默认实现 | 不破坏实现类的情况下给接口加新方法 |
| Metaspace替代PermGen | 方法区移到本地内存 | 不再OOM: PermGen space |
| CompletableFuture | 异步编程组合能力 | thenApply/thenCompose/thenCombine编排异步任务 |
JDK 11(2018.09 LTS)——模块化成熟、HTTP Client标准化:
| 特性 | 说明 | 实际价值 |
|---|---|---|
| Java Platform Module System | 从JDK 9开始的模块化(Project Jigsaw),JDK 11达稳定 | 拆大单体应用、控制可访问性、module-info.java声明依赖(团队小不一定需要) |
| HttpClient标准化 | java.net.http.HttpClient替代第三方库 | 原生支持HTTP/2、WebSocket、异步请求 |
| ZGC实验性 | 亚毫秒停顿GC | JDK 11首次引入(实验性),JDK 15生产可用 |
| Epsilon GC | 只分配内存不回收的"假GC" | 性能基准测试、短生命周期应用 |
| Flight Recorder开源 | JFR性能分析工具(原商业版) | 零性能损耗的生产环境Profiling |
| var局部变量推导 | var list = new ArrayList<String>() | 减少样板代码(从JDK 10开始) |
| 移除内容 | Java EE模块(JAXB/JAX-WS)被移除 | 迁移要注意:旧项目升级要额外加JAXB等依赖 |
| 收费政策 | Oracle JDK 11起商用收费 | OpenJDK免费,以此版本为分界线 |
JDK 17(2021.09 LTS)——当前主流LTS,G1/GC全面成熟:
| 特性 | 说明 | 实际价值 |
|---|---|---|
| Sealed Classes | sealed class Shape permits Circle, Rectangle | 受控继承,编译期保证子类列表,增强类型安全 |
| Pattern Matching for switch | switch支持类型匹配和解构(预览) | 减少instanceof+强转的模板代码 |
| Record类 | record Point(int x, int y){} 一行搞定数据载体 | 消除getter/setter/equals/hashCode/toString(从JDK 14正式) |
| Text Blocks | """...""" 多行文本块 | SQL/JSON/HTML不再用string拼接(从JDK 15正式) |
| 增强型伪随机数生成器 | 新接口+新算法(LXM系列) | 高性能多线程随机数生成 |
| Foreign Function & Memory API | 替代JNI的现代方案(孵化) | 安全高效调用C/C++代码 |
| macOS AArch64支持 | 原生支持Apple M1/M2芯片 | 无需Rosetta转译 |
| G1成为事实标准 | 多年打磨,大堆场景表现稳定 | 多数项目升级JDK 17的直接理由 |
JDK 21(2023.09 LTS)——最新LTS,虚拟线程时代来临:
| 特性 | 说明 | 实际价值 |
|---|---|---|
| Virtual Threads(虚拟线程) | Project Loom正式落地 | JDK 21最大卖点——数百万轻量级线程,阻塞操作几乎免费。Spring Boot 3.2已集成 |
| Pattern Matching for switch(正式) | switch模式匹配结束预览,正式GA | 类型安全+解构式编程 |
| Record Patterns | 嵌套解构Record对象 | if (p instanceof Point(int x, int y) && x > 0) |
| Sequenced Collections | 有序集合统一接口 getFirst()/getLast()/addFirst()/addLast() | List/Deque/SortedSet有统一的操作有序元素的API |
| String Templates(预览) | STR."Hello \{name}" 字符串模板 | 替代String.format和字符串拼接 |
| Scoped Values(预览) | 线程间共享不可变数据的新方案 | 替代ThreadLocal部分场景(轻量、明确生命周期) |
| Structured Concurrency(预览) | 结构化并发,StructuredTaskScope | 把多个并发子任务作为一个"工作单元"管理 |
| ZGC正式支持分代 | ZGC从单代发展为分代回收 | 进一步提升吞吐量 |
| Key Encapsulation Mechanism API | 抗量子加密(PQC)支持 | 面向未来的安全 |
LTS升级路径建议:
| |
实际项目选型经验:
目前主力在JDK 8上,原因是客户本地部署环境限制——很多客户只有JDK 8的授权或安全基线认证。升级到JDK 11/17的最大阻力不是技术(代码兼容性很好),而是客户的环境审批流程。但如果是新项目或云端部署,我会直接选JDK 17——Record+Sealed Classes提升代码表达力、G1比JDK 8的Parallel更稳定、长期支持到2029年。如果场景有高并发连接需求(比如Netty做数万设备同时接入),那我就选JDK 21——虚拟线程让一个TCP连接一个虚拟线程成为可能,代码模型从异步回调退化为同步写法但性能不降。
陷阱提示:把var说成"和JS一样动态类型"(var是编译期类型推断,运行时强类型);不知道JDK 11 Oracle JDK开始商用收费;不知道ZGC不同版本的状态(实验性/生产可用/分代);把Record和Lombok @Data简单等同(Record是不可变对象,Lombok是可变);不知道虚拟线程和平台线程的本质区别(虚拟线程由JVM调度,不绑定OS线程)。