1. 概述
Java 14 于 2020 年 3 月 17 日发布,距离上一版本 Java 13 正好六个月,符合 Java 新的发布节奏。
在本篇文章中,我们将总结 Java 14 中引入的新特性、预览特性、孵化特性以及被废弃或移除的功能。
我们还提供了更多关于 Java 14 的深入文章,帮助你更好地理解和使用这些新功能。
2. 从早期版本延续的功能
Java 14 中有一些功能是从前一版本延续而来的。下面我们逐一介绍。
2.1. Switch 表达式(JEP 361)
这个功能最早在 JDK 12 中以预览形式引入,在 Java 13 中继续作为预览功能存在。而在 Java 14 中,switch 表达式 已正式标准化,成为开发工具包的一部分。
这意味着你现在可以在生产代码中直接使用该功能,而不再仅限于实验性质的预览模式。
举个简单的例子:假设我们要判断一周中的某天是工作日还是周末:
在增强之前,我们通常会这样写:
boolean isTodayHoliday;
switch (day) {
case "MONDAY":
case "TUESDAY":
case "WEDNESDAY":
case "THURSDAY":
case "FRIDAY":
isTodayHoliday = false;
break;
case "SATURDAY":
case "SUNDAY":
isTodayHoliday = true;
break;
default:
throw new IllegalArgumentException("What's a " + day);
}
使用 switch 表达式之后,可以更简洁地表达同样的逻辑:
boolean isTodayHoliday = switch (day) {
case "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY" -> false;
case "SATURDAY", "SUNDAY" -> true;
default -> throw new IllegalArgumentException("What's a " + day);
};
2.2. 文本块(JEP 368)
文本块 继续向主流演进,目前仍处于预览阶段。
除了 JDK 13 提供的多行字符串支持外,第二轮预览新增了两个转义序列:
✅ \\
:表示行尾,避免引入换行符
✅ \\s
:代表一个空格
例如:
String multiline = "A quick brown fox jumps over a lazy dog; the lazy dog howls loudly.";
现在可以写成:
String multiline = """
A quick brown fox jumps over a lazy dog; \
the lazy dog howls loudly.""";
这种方式提高了代码可读性,并且不会在 dog;
后添加换行符。
3. 新增预览功能
3.1. instanceof 的模式匹配(JEP 305)
JDK 14 引入了对 instanceof 的模式匹配支持,目的是减少样板代码,提升开发效率。
来看一个简单例子:
以前我们会这样写:
if (obj instanceof String) {
String str = (String) obj;
int len = str.length();
// ...
}
现在可以直接在 instanceof 判断中绑定变量:
if (obj instanceof String str) {
int len = str.length();
// ...
}
未来版本中,Java 还计划将这种模式匹配扩展到其他结构中,比如 switch。
3.2. Records(JEP 359)
Records 是为了简化数据模型类(POJO)中大量重复代码而设计的。它不仅提升了开发效率,还能有效降低人为错误的风险。
例如,定义一个包含 id
和 password
的 User 数据模型可以这样写:
public record User(int id, String password) { };
这里我们使用了一个新的关键字 —— record
。仅通过这一行声明,Java 会自动为我们生成构造函数、getter 方法、equals()
、hashCode()
和 toString()
方法。
来看一段 JUnit 测试示例:
private User user1 = new User(0, "UserOne");
@Test
public void givenRecord_whenObjInitialized_thenValuesCanBeFetchedWithGetters() {
assertEquals(0, user1.id());
assertEquals("UserOne", user1.password());
}
@Test
public void whenRecord_thenEqualsImplemented() {
User user2 = user1;
assertTrue(user1, user2);
}
@Test
public void whenRecord_thenToStringImplemented() {
assertTrue(user1.toString().contains("UserOne"));
}
4. 新增正式功能
除了两个预览功能,Java 14 还带来了几个可以直接用于生产的功能。
4.1. 更具描述性的 NullPointerException(JEP 358)
过去,当发生 NullPointerException 时,异常堆栈信息通常只告诉你哪一行代码出错了,但并没有明确指出是哪个变量为 null。
虽然有用,但开发者仍需手动排查具体是哪个对象导致的问题。
现在 Java 改进了这一点,增加了提示信息,明确指出是哪个变量为 null。
例如:
int[] arr = null;
arr[0] = 1;
之前运行这段代码,日志输出可能是:
Exception in thread "main" java.lang.NullPointerException
at com.baeldung.MyClass.main(MyClass.java:27)
而现在,同样的场景下,日志可能变成:
java.lang.NullPointerException: Cannot store to int array because "a" is null
这样一看就知道是变量 a
为 null 导致的异常。
5. 孵化功能
这些是非最终版本的 API 或工具,Java 团队提供出来供开发者试用。它们不同于预览功能,属于独立模块,包名以 jdk.incubator 开头。
5.1. 外部内存访问 API(JEP 370)
这是一个 新 API,允许 Java 程序安全高效地访问堆外内存(如本地内存)。
许多 Java 库如 mapDB 和 memcached 都需要操作堆外内存,因此迫切需要一个标准解决方案。JEP 370 就是为此提出的替代方案,取代了旧有的 ByteBuffer 和 sun.misc.Unsafe。
该 API 基于三个核心抽象:MemorySegment、MemoryAddress 和 MemoryLayout,提供了统一的安全访问方式。
5.2. 打包工具(JEP 343)
传统上,Java 开发者交付应用程序的方式是打包成 JAR 文件,由用户在自己的 JVM 中运行。
但现实中,用户更希望获得一个双击即可安装的安装包(如 Windows 上的 exe 或 macOS 上的 dmg)。
这个 JEP 正是为了解决这个问题。开发者可以使用 jlink 来精简 JDK 模块,再通过打包工具生成轻量级镜像,实现跨平台安装。
6. JVM/HotSpot 相关特性
6.1. ZGC 支持 Windows(JEP 365)和 macOS(JEP 364)—— 实验性
Z 垃圾收集器 是一个可扩展、低延迟的 GC,在 Java 11 中首次作为实验性功能引入,最初仅支持 Linux/x64。
由于 ZGC 在 Linux 平台获得了积极反馈,Java 14 将其支持扩展到了 Windows 和 macOS。尽管仍是实验性功能,但预计将在 下一个 JDK 版本 中转正。
6.2. G1 的 NUMA 感知内存分配(JEP 345)
NUMA(非统一内存访问)机制此前只在 Parallel GC 中实现,未在 G1 中支持。
考虑到 NUMA 能显著提升多插槽环境下单个 JVM 的性能表现,该 JEP 引入了对 G1 GC 的 NUMA 感知能力。
目前没有计划将其推广至其他 HotSpot 收集器。
6.3. JFR 事件流(JEP 349)
通过这项增强,JDK Flight Recorder 的数据现在可以持续监控。主要改动在于 jdk.jfr.consumer 包,用户现在可以直接读取或流式处理录制数据。
7. 被废弃或移除的功能
Java 14 废弃了以下功能:
❌ Solaris 和 SPARC 移植版本(JEP 362)—— 因为这些 Unix 系统和 RISC 处理器近年来已停止活跃开发
❌ ParallelScavenge + SerialOld GC 组合(JEP 366)—— 使用频率极低,维护成本高
此外,也有几个功能被彻底移除:
❌ 并发标记清除(CMS)垃圾收集器(JEP 363)—— Java 9 中已被弃用,G1 成为默认 GC,且有 ZGC、Shenandoah 等更优替代方案
❌ Pack200 工具与 API(JEP 367)—— Java 11 中已标记为待删除,现在正式移除
8. 总结
本文总结了 Java 14 中的各项 JEP。
总体来说,Java 14 共包含 16 个主要更新,涵盖新功能、预览功能、孵化功能、废弃和移除项等。
我们结合示例代码逐一介绍了这些特性,帮助你快速掌握 Java 14 的关键变化。
一如既往,所有源码均可在 GitHub 获取。