Java 12 & 13 新特性概览
Java 12 与 13 是两个非 LTS 版本,重头戏是两个语言级预览特性:switch 表达式和文本块。它们分别在 Java 14、15 转正,也为后来的模式匹配铺了路。
版本定位
JDK 12 发布于 2019 年 3 月,JDK 13 发布于同年 9 月,都不是长期支持版本。这两个版本的语言改动以预览为主:switch 表达式在 12 首次预览,13 二次预览并补上 yield;文本块在 13 首次预览。JVM 侧,12 实验性引入低暂停收集器 Shenandoah,13 让 ZGC 学会把闲置内存还给操作系统。对日常业务代码影响最直接的,还是那两个预览语法。
switch 表达式(预览)
传统 switch 是语句而不是表达式:每个 case 结尾靠 break 防穿透,漏写一个就静默落入下一分支,这是 Java 新手最常见的 bug 来源之一。而且旧 switch 无法直接产出一个值,想按分支赋值只能先声明变量再逐个分支填写,既啰嗦又容易漏。
Java 12 的预览版本引入箭头分支,并让 switch 可以像表达式一样求值:
String result = switch (day) { |
箭头右侧直接就是分支结果,多个标签可用逗号合并,天然不穿透,break 随之退场。Java 13 的二次预览补上 yield 关键字,用于在需要多行逻辑的分支里产出值:
int score = switch (level) { |
yield 只结束当前分支并给出表达式的值,与 return 结束整个方法是两回事。使用注意:switch 表达式必须穷尽所有可能取值——枚举全覆盖或提供 default——否则编译报错。这反而是好事,漏分支的错误被提前到了编译期。
文本块(预览)
痛点很明确:在 Java 里写 JSON、SQL、HTML 这类多行字符串,过去只能靠 + 拼接加 \n 转义,可读性极差,改一行要动好几处引号。
Java 13 预览的文本块用一对三重双引号界定,中间的内容原样成为字符串,包括换行:
String json = """ |
编译器会根据结束引号的位置自动剥除公共缩进。注意两点:一是开始引号之后必须换行,否则编译失败;二是此时转义细节尚未定稿(Java 14 才补充 \ 行尾续行与 \s 空格转义),预览阶段在小范围试用即可,别急着全量替换项目里的模板代码。
Shenandoah 与 GC 动态
Java 12 以实验特性引入 Shenandoah——Red Hat 主导的低暂停垃圾收集器。它的目标是把 GC 停顿压到毫秒级,且停顿时长基本不随堆大小增长,思路是让大部分回收工作与应用线程并发执行。它与 ZGC 定位相近,当时的一大卖点是向 JDK 8u 回移植,在 Java 8 仍占主流的年代落地门槛更低。Java 13 则改进了 ZGC:长时间未使用的堆页面会主动归还给操作系统,容器环境下的内存占用表现更友好。
预览特性是什么、怎么开
预览特性指设计、规格、实现都已完整,但尚未承诺永久保留的语法或 API,后续版本可能调整甚至移除。编译和运行带预览特性的代码必须显式开启:
javac --enable-preview --release 13 Main.java |
编译与运行两侧都要加参数,且运行所用 JDK 主版本必须与编译时一致,否则 class 文件会被拒绝加载。工程建议:个人学习、内部工具随意尝鲜;对外交付的类库和核心服务慎用,避免语法定型时被迫返工。
升级建议
非 LTS 版本官方支持周期只有半年,不建议生产环境追新。合理姿势是在开发机上安装体验,把 switch 表达式和文本块的写法练熟,等它们转正后随下一个 LTS 一并启用。GC 侧继续用默认的 G1 即可,Shenandoah 此时仍属尝鲜性质。
小结
- switch 表达式预览:箭头分支消灭穿透,yield 负责复杂分支产出值,穷尽性检查把漏分支提前暴露。
- 文本块预览:三引号多行字符串让 JSON/SQL 模板的可读性翻身,转义规则留待后续版本定稿。
- Shenandoah 实验性入场、ZGC 学会归还内存,低暂停 GC 进入双线竞速阶段。
- 预览特性需
--enable-preview显式开启,用来学语法可以,上生产要慎重。

