【JAVA】常用的JDK8、JDK17 以及 JDK21 的主要新特性和演进过程
JDK8、JDK17 以及 JDK21 的主要新特性和演进过程。
一、JDK8 的特性
JDK8 是 Java 语言历史上具有里程碑意义的版本,主要特性包括:
-
Lambda 表达式
引入了函数式编程风格,使得代码更加简洁。
示例代码:Runnable r = () -> System.out.println("Hello, JDK8"); r.run();
-
Stream API
便于对集合进行过滤、映射、规约等操作,支持函数式操作数据流。
示例代码:List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); int sum = numbers.stream().filter(n -> n % 2 == 0).mapToInt(Integer::intValue).sum(); System.out.println(sum);
-
默认方法(Default Methods)
允许接口提供方法默认实现,便于接口演进。
示例代码:interface MyInterface { default void sayHello() { System.out.println("Hello from default method"); } }
-
Optional 类
用于显式处理可能为空的值,减少 NullPointerException 风险。
示例代码:Optional<String> optional = Optional.of("JDK8"); optional.ifPresent(System.out::println);
-
新的日期/时间 API(java.time 包)
提供了更清晰、不可变的日期时间处理方式,替代旧的 Date 和 Calendar 类。
示例代码:LocalDate today = LocalDate.now(); System.out.println(today);
-
Nashorn JavaScript 引擎
内置 JavaScript 运行环境,方便在 Java 中运行 JS 代码(JDK15 后该引擎被移除)。
二、从 JDK8 到 JDK17 之间的主要特性演进及 JDK17 的特性
2.1 从 JDK8 到 JDK17 的总体演进摘要
在 JDK8 之后到 JDK17 之间,Java 生态经历了以下几个关键变化:
- 模块化系统(Project Jigsaw)(JDK9):将庞大的 JDK 拆分为模块,改善封装性、安全性和发布方式。
- 交互式工具 JShell(JDK9):提供了 REPL 环境,方便学习和快速原型开发。
- 局部变量类型推断(var 关键字)(JDK10):大大减少了冗长的类型声明。
- HTTP Client API 的标准化(JDK11):替代了旧的 HTTP 处理方式,支持 HTTP/2。
- 新增的 String 方法(如 isBlank、strip、lines、repeat 等)在 JDK11 中出现,提升了字符串处理的便利性。
- switch 表达式、文本块、records、pattern matching 等预览和新语法:从 JDK12 至 JDK16,这些特性不断试验、完善,并逐步部分标准化。
- 隐式类型模式匹配与 sealed classes:在 JDK15-17 中逐步引入并完善,使得面向对象结构更加安全和清晰。
2.2 JDK17 的主要特性
JDK17(LTS 版本)在这些演变的基础上,更加成熟地引入了以下关键特性:
-
Sealed Classes(密封类)
限制哪些类或接口可以扩展或实现某个超类型,帮助设计更安全的类层次结构。
示例代码:public sealed interface Shape permits Circle, Rectangle { } public final class Circle implements Shape { /* ... */ } public final class Rectangle implements Shape { /* ... */ }
-
Pattern Matching for switch(预览)
将模式匹配扩展到 switch 语句中,让分支判断更加简洁。
示例代码(预览形式):Object obj = "JDK17 Feature"; switch (obj) { case String s -> System.out.println(s.toUpperCase()); default -> System.out.println("Unknown type"); }
-
Foreign Function & Memory API(孵化中)
提供安全高效的方式访问 Java 堆之外的内存和调用本地代码,替代传统 JNI。
(此特性目前仍在孵化阶段,具体代码示例通常较为复杂,此处不做详细展开。) -
其它改进
例如增强的随机数生成器 API、改进的垃圾收集器(如 ZGC)、改良的 Nest-Based Access Control 等,进一步提升了语言的性能和可用性。
三、从 JDK17 到 JDK21 之间的主要特性演进及 JDK21 的特性
3.1 从 JDK17 到 JDK21 的总体演进摘要
在 JDK17 之后到 JDK21 之间,Java 继续稳步演进,主要变化包括:
- 虚拟线程(Virtual Threads):由 Project Loom 推出,旨在大幅简化高并发编程,降低线程开销。
- 结构化并发(Structured Concurrency):提供一种将多个并发任务作为一个整体管理的编程模型,使错误处理和资源管理更直观。
- Scoped Values:作为 ThreadLocal 的现代替代方案,用于在特定作用域内安全传递只读数据,避免内存泄露问题。
- Record Patterns 与 Pattern Matching for switch 进一步成熟:这些功能在预览后经过不断优化,使得在模式匹配解构记录时更为简洁和安全。
- Foreign Function & Memory API 的进一步完善:从孵化到预览的提升,使得与本地代码交互更稳定高效。
3.2 JDK21 的主要特性
JDK21 在上述演进的基础上,正式推出或进一步完善了以下关键特性:
-
Scoped Values(孵化/预览)
提供一种更安全的线程局部存储方案,替代传统的 ThreadLocal,避免因持久存储而导致的内存泄漏问题。
示例代码(伪代码形式):// 创建一个 ScopedValue 实例(通常为静态字段) ScopedValue<String> greeting = ScopedValue.newInstance(); // 在某个作用域内设置 ScopedValue 的值 ScopedValue.where(greeting, "Hello, JDK21", () -> { // 在此作用域中可以获取到刚刚设置的值 System.out.println(greeting.get()); // 输出 "Hello, JDK21" });
-
虚拟线程(Virtual Threads)
虚拟线程已经从预览逐步成熟,允许开发者以轻量级线程管理高并发场景,极大简化了并发编程。
示例代码:try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { executor.submit(() -> System.out.println("Running in a virtual thread!")); }
-
Record Patterns 的进一步成熟
Record Patterns 使得在进行记录(record)解构时无需冗长的显式调用,进一步简化代码。
示例代码:record Point(int x, int y) { } Object obj = new Point(3, 4); if (obj instanceof Point(int x, int y)) { System.out.println("x: " + x + ", y: " + y); }
-
Pattern Matching for switch(进一步优化,可能已稳定)
让 switch 语句可以直接根据对象类型和匹配条件分支处理,代码更简洁。
示例代码(示意):Object data = /*...*/; switch (data) { case Integer i when i > 0 -> System.out.println("Positive integer: " + i); case String s -> System.out.println("String: " + s); default -> System.out.println("Other type"); }
-
Foreign Function & Memory API(预览提升)
进一步优化了调用本地函数和访问堆外内存的安全性与效率,为高性能计算和与原生库交互提供更佳支持。(此部分代码较复杂,此处略。) -
结构化并发(Structured Concurrency)
通过将多个并发任务组合为一个整体,简化错误处理和任务取消的逻辑。
示例代码(示意):try (var scope = new StructuredTaskScope.ShutdownOnFailure()) { Future<String> result1 = scope.fork(() -> "Task1 result"); Future<String> result2 = scope.fork(() -> "Task2 result"); scope.join(); // 等待所有任务完成 System.out.println(result1.resultNow() + ", " + result2.resultNow()); }
-
其它细微优化和 API 改进
如对集合、字符串、日期时间等 API 的进一步增强,保证语言整体的一致性和高性能。
总结
- JDK8 重点推出了Lambda 表达式、Stream API、默认方法、Optional 和全新的日期时间 API,大幅提升了代码表达能力和开发效率。
- 从 JDK8 到 JDK17 期间,Java 不仅引入了模块化、var、JShell、HTTP Client、以及一系列新字符串与 switch 语法改进,还逐步试验了 Records、Pattern Matching 和 Sealed Classes 等新语法。
在 JDK17 中,Sealed Classes 正式定型、Pattern Matching for switch(预览)、Foreign Function & Memory API(孵化) 等成为该版本的亮点特性,并进一步完善了线程、垃圾收集器等底层优化。 - 从 JDK17 到 JDK21 期间,Java 的并发和与本地代码交互能力得到了显著提升。JDK21 则在此基础上引入了Scoped Values(替代传统 ThreadLocal)、虚拟线程(正式或进一步成熟)、Record Patterns、以及结构化并发等特性,使得并发编程更为高效、简洁,API 之间的协作也更加优雅。