Java 8 到 Java 25 主要特性
在笔者编写这篇文章的时候,Java 25 LTS 版本已发布,目前的LTS版本分别是:Java 8、Java 11、Java 17、Java 21、Java 25。
Java 8 (LTS)
发布日期:2014年3月18日
- Lambda 表达式:
(params) -> expression, 支持函数式编程,使代码更简洁。1
2
3// Lambda表达式示例
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.forEach(name -> System.out.println(name)); - Stream API: 对集合进行复杂的流水线操作(
filter,map,reduce等),支持并行处理。1
2
3
4
5// Stream API示例
List<String> filteredNames = names.stream()
.filter(name -> name.startsWith("A"))
.map(String::toUpperCase)
.collect(Collectors.toList()); - 方法引用:
Class::method, 进一步简化Lambda表达式。 - 默认方法: 允许在接口中提供默认实现,便于接口演进。
- 新的日期时间 API: 引入
java.time包(LocalDate,LocalTime,Instant等),解决了旧Date/Calendar类的诸多问题。1
2
3
4// 新日期时间API示例
LocalDate today = LocalDate.now();
LocalDate specificDate = LocalDate.of(2023, Month.SEPTEMBER, 19);
Period period = Period.between(today, specificDate); - Optional: 容器类,用于更优雅地处理可能为
null的值。1
2
3// Optional示例
Optional<String> optionalName = Optional.ofNullable(getName());
String result = optionalName.orElse("Default Name");
Java 9
发布日期:2017年9月21日
- 模块系统 (JPMS): 引入
module-info.java,允许开发者定义模块及其依赖和导出包,实现强封装和更清晰的结构。1
2
3
4
5// module-info.java示例
module com.example.myapp {
requires java.sql;
exports com.example.myapp.api;
} - JShell: Java REPL(交互式编程环境),便于快速测试代码片段。
- 集合工厂方法:
List.of(),Set.of(),Map.of()等,快速创建不可变集合。1
2
3
4// 集合工厂方法示例
List<String> immutableList = List.of("a", "b", "c");
Set<String> immutableSet = Set.of("a", "b", "c");
Map<String, Integer> immutableMap = Map.of("a", 1, "b", 2); - 接口私有方法: 允许在接口中定义私有方法,用于提取公共代码。
Java 10
发布日期:2018年3月20日
- 局部变量类型推断: 使用
var关键字声明局部变量,编译器根据初始值推断类型。var list = new ArrayList<String>();1
2
3// var示例
var list = new ArrayList<String>(); // 推断为ArrayList<String>
var stream = list.stream(); // 推断为Stream<String>
Java 11 (LTS) - 下一个企业级基准
发布日期:2018年9月25日
- HTTP Client (标准): 在 Java 9 引入孵化器后,正式成为标准API,支持同步和异步编程模式。
1
2
3
4
5
6// HTTP Client示例
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/users"))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); - 启动单文件源码程序: 直接运行
.java单文件源程序,无需先编译javac。 - String 增强:
lines(),isBlank(),strip()等新方法。1
2
3
4
5
6
7// String新方法示例
String multiLine = "Hello\nWorld\nJava";
multiLine.lines().forEach(System.out::println);
String text = " Java 11 ";
System.out.println(text.strip()); // "Java 11"
System.out.println(text.isBlank()); // false - 移除模块: 移除了 Java EE 和 CORBA 模块(需要时需单独引入依赖)。
Java 12
发布日期:2019年3月19日
- Switch 表达式 (预览): 允许
switch直接返回值,并使用->语法避免break。1
2
3
4
5
6
7
8// Switch表达式示例
DayOfWeek day = DayOfWeek.WEDNESDAY;
int lengthOfDay = switch (day) {
case MONDAY, FRIDAY, SUNDAY -> 6;
case TUESDAY -> 7;
case THURSDAY, SATURDAY -> 8;
case WEDNESDAY -> 9;
}; - 有用的 NullPointerExceptions: 更详细地指出到底是哪个变量为
null。
Java 13
发布日期:2019年9月17日
- Switch 表达式 (第二次预览): 继续改进。
- 文本块 (预览): 使用三重引号
"""..."""定义多行字符串,大幅改善JSON、SQL等字符串的可读性。1
2
3
4
5
6
7
8// 文本块示例
String json = """
{
"name": "John Doe",
"age": 30,
"email": "john.doe@example.com"
}
""";
Java 14
发布日期:2020年3月17日
- Switch 表达式 (标准): 在预览两个版本后成为标准特性。
instanceof模式匹配 (预览): 简化了在instanceof检查后,直接进行类型转换的代码。1
2
3
4// instanceof模式匹配示例
if (obj instanceof String s) {
System.out.println(s.toUpperCase());
}- Records (预览): 提供了一种简洁的语法来声明主要目的是保存数据的不可变类。
record Point(int x, int y) { }1
2
3
4
5
6
7
8
9
10
11// Record示例
record Point(int x, int y) {
public double distance() {
return Math.sqrt(x * x + y * y);
}
}
Point p = new Point(3, 4);
System.out.println(p.x()); // 3
System.out.println(p.y()); // 4
System.out.println(p); // Point[x=3, y=4]
Java 15
发布日期:2020年9月15日
- Sealed Classes (密封类) (预览): 允许控制哪些类可以继承或实现它,为模式匹配提供坚实基础。
permits关键字。1
2
3
4
5
6
7
8
9
10
11
12
13
14// 密封类示例
public sealed class Shape permits Circle, Rectangle, Square {
// 基类定义
}
public final class Circle extends Shape {
private double radius;
// Circle特定实现
}
public non-sealed class Rectangle extends Shape {
private double width, height;
// Rectangle特定实现
} - 文本块 (标准): 在预览两个版本后成为标准特性。
- Records (第二次预览): 继续改进。
Java 16
发布日期:2021年3月16日
- Records (标准): 在预览两个版本后成为标准特性。
- 模式匹配 for
instanceof(标准): 在预览后成为标准特性。 jpackage工具: 用于打包自包含的 Java 应用程序。
Java 17 (LTS)
发布日期:2021年9月14日
- Sealed Classes (密封类) (标准): 在预览两个版本后成为标准特性。
- 上下文特定的反序列化过滤器: 允许应用程序通过API配置反序列化过滤器,防止反序列化攻击。
Java 18
发布日期:2022年3月22日
- 简单Web服务器: 提供命令行工具和API,用于原型设计和教育。
1
2# 启动简单Web服务器
jwebserver - UTF-8 作为默认字符集: 在所有平台上,默认将UTF-8作为标准字符集。
Java 19
发布日期:2022年9月20日
- 虚拟线程 (预览): 重大特性! 轻量级线程,极大简化了高吞吐量并发应用的开发,旨在”一个请求一个线程”而无需池化。
1
2
3
4
5
6
7
8
9// 虚拟线程示例
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
IntStream.range(0, 10_000).forEach(i -> {
executor.submit(() -> {
Thread.sleep(Duration.ofSeconds(1));
return i;
});
});
} - 外部函数和内存API (预览): 取代JNI,更安全、高效地访问本地代码和内存。
switch的模式匹配 (第三次预览): 持续改进。
Java 20
发布日期:2023年3月21日
- 虚拟线程 (第二次预览): 根据反馈进行细微调整。
- Scoped Values (预览): 允许在线程内和子线程间共享不可变数据,是
ThreadLocal的更好替代方案。 - Record 模式 (第二次预览): 在模式匹配中解构 Record,例如
if (obj instanceof Point(int x, int y)) { ... }。1
2
3
4// Record模式示例
if (obj instanceof Point(int x, int y)) {
System.out.println(x + y);
}
Java 21 (LTS)
发布日期:2023年9月19日
- 虚拟线程 (正式): 从预览变为正式特性,这是 Java 21 最核心的特性,将改变Java并发编程的方式。
1
2
3
4
5
6
7// 虚拟线程正式版示例
void handleRequest(HttpRequest request, HttpResponse response) {
var url = request.getURI();
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
executor.submit(() -> fetchAndProcess(url));
}
} - 分代 ZGC: 对 ZGC 垃圾收集器进行分代管理,显著减少垃圾收集的开销。
- Record 模式 (正式): 成为标准特性。
switch的模式匹配 (正式):1
2
3
4
5
6
7
8// switch模式匹配正式版示例
String formatted = switch (obj) {
case Integer i -> String.format("int %d", i);
case Long l -> String.format("long %d", l);
case Double d -> String.format("double %f", d);
case String s -> String.format("String %s", s);
default -> obj.toString();
};- 序列化集合: 为集合接口增加了新的静态工厂方法,用于创建不可变的序列化集合。
Java 22
发布日期:2024年3月19日
- 未命名模式和变量 (标准)
1 | // 传统方式 |
- 字符串模板 (第二次预览)
1 | String name = "John"; |
Java 23
发布日期:2024年9月17日
- 结构化并发 (第二次预览)
1 | try (var scope = new StructuredTaskScope.ShutdownOnFailure()) { |
- 外部函数和内存API (第三次预览)
1 | // 调用C标准库的strlen函数 |
Java 24
发布日期:2025年3月18日
- Vector API (第七次孵化)
1 | var species = IntVector.SPECIES_PREFERRED; |
- 值对象 (预览)
1 | value class Point { |
Java 25 (LTS)
发布日期:2025年9月17日
https://openjdk.org/projects/jdk/25/
1 | 470: PEM Encodings of Cryptographic Objects (Preview) |
- 作用域值(Scoped Values)
可以在线程内和线程间共享不可变的数据,优于线程局部变量 ThreadLocal ,尤其是在使用大量虚拟线程时
1 | final static ScopedValue<...> V = new ScopedValue<>(); |
- 紧凑源文件与实例主方法
简化 main 函数
1 | void main() { |
总结与建议
| 版本 | 性质 | 发布日期 | 核心意义 |
|---|---|---|---|
| Java 8 | LTS | 2014-03-18 | 函数式编程、Stream API、新日期API,现代化起点 |
| Java 11 | LTS | 2018-09-25 | HTTP客户端、单文件运行、长期支持基准 |
| Java 17 | LTS | 2021-09-14 | Sealed Classes、Pattern Matching、Records成型,当前主流LTS |
| Java 21 | LTS | 2023-09-19 | 虚拟线程、分代ZGC,新一代并发模型 |
| Java 25 | LTS | 2023-09-17 | 作用域值(Scoped Values)、紧凑源文件与实例主方法 |