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) {
case MONDAY, FRIDAY, SUNDAY -> "工作日边缘";
case TUESDAY, WEDNESDAY, THURSDAY -> "工作日核心";
case SATURDAY -> "周末";
};

箭头右侧直接就是分支结果,多个标签可用逗号合并,天然不穿透,break 随之退场。Java 13 的二次预览补上 yield 关键字,用于在需要多行逻辑的分支里产出值:

int score = switch (level) {
case "A" -> 90;
default -> {
log.warn("未知等级: {}", level);
yield 0;
}
};

yield 只结束当前分支并给出表达式的值,与 return 结束整个方法是两回事。使用注意:switch 表达式必须穷尽所有可能取值——枚举全覆盖或提供 default——否则编译报错。这反而是好事,漏分支的错误被提前到了编译期。

文本块(预览)

痛点很明确:在 Java 里写 JSON、SQL、HTML 这类多行字符串,过去只能靠 + 拼接加 \n 转义,可读性极差,改一行要动好几处引号。

Java 13 预览的文本块用一对三重双引号界定,中间的内容原样成为字符串,包括换行:

String json = """
{
"name": "Times",
"tags": ["java", "jvm"]
}
""";

编译器会根据结束引号的位置自动剥除公共缩进。注意两点:一是开始引号之后必须换行,否则编译失败;二是此时转义细节尚未定稿(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
java --enable-preview Main

编译与运行两侧都要加参数,且运行所用 JDK 主版本必须与编译时一致,否则 class 文件会被拒绝加载。工程建议:个人学习、内部工具随意尝鲜;对外交付的类库和核心服务慎用,避免语法定型时被迫返工。

升级建议

非 LTS 版本官方支持周期只有半年,不建议生产环境追新。合理姿势是在开发机上安装体验,把 switch 表达式和文本块的写法练熟,等它们转正后随下一个 LTS 一并启用。GC 侧继续用默认的 G1 即可,Shenandoah 此时仍属尝鲜性质。

小结

  • switch 表达式预览:箭头分支消灭穿透,yield 负责复杂分支产出值,穷尽性检查把漏分支提前暴露。
  • 文本块预览:三引号多行字符串让 JSON/SQL 模板的可读性翻身,转义规则留待后续版本定稿。
  • Shenandoah 实验性入场、ZGC 学会归还内存,低暂停 GC 进入双线竞速阶段。
  • 预览特性需 --enable-preview 显式开启,用来学语法可以,上生产要慎重。