JDK 1.8 到JDK21的重大差异和优化
前言
Java作为最流行的编程语言之一,在过去十年中经历了巨大的发展。从JDK 1.8发布以来,Oracle和其他贡献者持续为Java平台带来创新和改进。本文将详细介绍从JDK 1.8到最新版本(JDK 21)的一些重大变化和优化,帮助开发者了解Java的发展历程和未来趋势。
JDK 1.8 的里程碑特性
JDK 1.8(也称为Java 8)是Java历史上最重要的版本之一,引入了许多革命性的特性:
Lambda 表达式
Lambda表达式使Java具备了函数式编程的能力,大大简化了代码编写:
// Java 8之前
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
Collections.sort(names, new Comparator<String>() {
@Override
public int compare(String a, String b) {
return a.compareTo(b);
}
});
// Java 8之后
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.sort((a, b) -> a.compareTo(b));
Stream API
Stream API提供了处理集合数据的新方式:
List<String> names = people.stream()
.filter(person -> person.getAge() > 18)
.map(Person::getName)
.collect(Collectors.toList());
新的日期时间API
取代了旧的Date和Calendar类:
LocalDateTime now = LocalDateTime.now();
LocalDate tomorrow = LocalDate.now().plusDays(1);
后续版本的重大变化
JDK 9 - 模块化系统(Project Jigsaw)
JDK 9引入了Java平台模块系统(JPMS),这是Java历史上最具争议但也最重要的变化之一:
module my.module {
requires java.base;
requires java.logging;
exports com.mycompany.mypackage;
}
模块化系统带来的好处:
- 更强的封装性
- 明确的依赖关系
- 更小的运行时镜像
- 提高安全性
JDK 10 - 局部变量类型推断
引入var关键字简化局部变量声明:
// JDK 10之前
List<String> names = new ArrayList<String>();
// JDK 10之后
var names = new ArrayList<String>();
JDK 11 - 长期支持版本
JDK 11是继JDK 8之后的第一个长期支持(LTS)版本,引入了一些实用特性:
- HTTP Client标准化
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://example.com"))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
- 字符串增强方法
" ".isBlank(); // true
"Java".repeat(3); // "JavaJavaJava"
" Java ".strip(); // "Java"
JDK 12-16 的重要更新
Switch Expressions(JDK 12预览,JDK 14正式)
// 传统switch
String result;
switch (day) {
case MONDAY:
case FRIDAY:
case SUNDAY:
result = "6 AM";
break;
case TUESDAY:
result = "7 AM";
break;
default:
result = "8 AM";
}
// 新的switch表达式
String result = switch (day) {
case MONDAY, FRIDAY, SUNDAY -> "6 AM";
case TUESDAY -> "7 AM";
default -> "8 AM";
};
Text Blocks(JDK 13预览,JDK 15正式)
String html = """
<html>
<body>
<p>Hello, world</p>
</body>
</html>
""";
Records(JDK 14预览,JDK 16正式)
public record Person(String name, int age) {
// 自动生成构造函数、getter、equals、hashCode和toString
}
JDK 17 - 最新的LTS版本
JDK 17于2021年9月发布,是目前最新的长期支持版本:
Sealed Classes(密封类)
public abstract sealed class Shape
permits Circle, Rectangle, Square { }
public final class Circle extends Shape { }
public final class Rectangle extends Shape { }
public final class Square extends Shape { }
Pattern Matching for instanceof(JDK 14预览,JDK 16正式)
// 以前的写法
if (obj instanceof String) {
String str = (String) obj;
System.out.println(str.length());
}
// 新的写法
if (obj instanceof String str) {
System.out.println(str.length());
}
JDK 21 - 最新特性
JDK 21于2023年9月发布,带来了几个重要的预览特性:
Virtual Threads(虚拟线程)
虚拟线程是Java并发模型的重大革新,极大地简化了高并发应用的开发:
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
IntStream.range(0, 10_000).forEach(i -> {
executor.submit(() -> {
// 每个任务都在自己的虚拟线程中运行
Thread.sleep(Duration.ofSeconds(1));
System.out.println("Task " + i + " completed");
});
});
}
// 所有任务并发执行,但只需少量平台线程
Sequenced Collections(序列化集合)
为Collection层次结构添加了新的接口和方法:
List<String> list = new ArrayList<>();
list.addFirst("first");
list.addLast("last");
String first = list.getFirst();
String last = list.getLast();
Record Patterns(记录模式)
增强了模式匹配能力:
record Point(int x, int y) {}
void printPoint(Object obj) {
if (obj instanceof Point(int x, int y)) {
System.out.println("Point: (" + x + ", " + y + ")");
}
}
JVM层面的重大优化
GraalVM
GraalVM是一个高性能的JVM实现,支持多语言运行和原生镜像生成:
# 生成原生镜像
native-image -jar myapp.jar
ZGC 和 Shenandoah GC
新一代垃圾收集器,提供极低的暂停时间:
# 启用ZGC
java -XX:+UseZGC MyApp
启动时间和内存占用优化
每个版本都在启动时间和内存占用方面有所改善,特别是在微服务和容器化环境中表现明显。
性能改进总结
| 版本 | 主要性能改进 |
|---|---|
| JDK 9 | G1成为默认GC,字符串内部表示优化 |
| JDK 10 | 局部变量类型推断减少样板代码 |
| JDK 11 | HTTP/2客户端,飞行记录器(Flight Recorder)开源 |
| JDK 12 | Shenandoah GC(实验性) |
| JDK 13 | ZGC改进,Socket API重新实现 |
| JDK 14 | NUMA内存感知,G1 NUMA感知 |
| JDK 15 | ZGC产品化,Shenandoah GC产品化 |
| JDK 16 | ZGC并发栈遍历,弹性元空间 |
| JDK 17 | 应用程序类数据共享(AppCDS)增强 |
| JDK 18 | 默认UTF-8编码,简单Web服务器 |
| JDK 19 | 虚拟线程(预览),结构化并发(预览) |
| JDK 20 | 虚拟线程(第二次预览),scoped values(预览) |
| JDK 21 | 虚拟线程正式发布,序列化集合 |
迁移建议
从JDK 8迁移到新版本
- 逐步升级:先升级到JDK 11或JDK 17 LTS版本
- 检查废弃API:关注被标记为deprecated的API
- 模块化适配:如果使用模块系统,需要适配JPMS
- 依赖更新:确保第三方库兼容新版本JDK
关键注意事项
- 向后兼容性:Java保持很强的向后兼容性,大部分应用可以直接运行在新版本上
- 性能调优:新版本可能需要重新调优JVM参数
- 安全更新:定期升级到最新补丁版本以获得安全修复
未来发展趋势
Project Loom
虚拟线程只是Project Loom的一部分,未来还将包括:
- 结构化并发
- Scoped Values
- Continuations
Project Panama
旨在改善Java与本地代码的互操作性:
- Foreign Function & Memory API
- Vector API
Project Valhalla
专注于值类型和泛型特化,进一步提高性能。
总结
从JDK 1.8到最新版本,Java经历了显著的演进:
- 语言层面:函数式编程、模块化、模式匹配等现代化特性
- JVM层面:垃圾收集器改进、启动性能优化、内存管理增强
- 生态系统:工具链完善、微服务支持、云原生适配
对于开发者而言,及时跟进Java的新特性和最佳实践,可以显著提升开发效率和应用性能。建议企业根据自身情况制定合理的升级计划,充分利用Java平台的最新成果。
选择合适的JDK版本也很重要:
- 如果追求稳定性,选择LTS版本(JDK 8、11、17、21)
- 如果希望尝试最新特性,可以选择最新的GA版本
- 在生产环境中,充分测试后再进行升级





