Java 21作为LTS(长期支持)版本于2023年9月正式发布,带来了多项改进和新功能,极大地提升了开发效率和代码表现。本文将深入解析Java 21的核心新特性,帮助开发者快速掌握并应用于实际项目中。
1. 记录模式(Record Patterns)
记录模式扩展了Java 16引入的记录类型,实现了更灵活的数据解构功能。这一特性特别适合处理复杂的嵌套数据结构。
java
record Point(int x, int y) {}
record Rectangle(Point upperLeft, Point lowerRight) {}
void printRectangle(Rectangle r) {
// 记录模式解构
if (r instanceof Rectangle(Point(int x1, int y1), Point(int x2, int y2))) {
System.out.println("坐标: (" + x1 + ", " + y1 + ") - (" + x2 + ", " + y2 + ")");
}
}
2. 模式匹配switch表达式(Pattern Matching for switch)
Java 21正式确定了模式匹配switch特性,支持在case分支中使用不同类型模式,显著简化了类型检查和转换逻辑:
java
Object obj = // 某个对象
String result = switch (obj) {
case Integer i -> "整数: " + i;
case String s when s.length() > 5 -> "长字符串: " + s;
case String s -> "短字符串: " + s;
case Point p -> "点坐标: (" + p.x() + ", " + p.y() + ")";
case null -> "空值";
default -> "其他类型: " + obj.getClass().getName();
};
3. 虚拟线程(Virtual Threads)
Java 21最激动人心的特性之一是虚拟线程的正式发布。虚拟线程是轻量级线程实现,可以创建数百万个实例而不会耗尽系统资源,非常适合I/O密集型应用:
java
// 创建单个虚拟线程
Thread vThread = Thread.startVirtualThread(() -> {
System.out.println("在虚拟线程中执行");
});
// 创建大量虚拟线程
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
IntStream.range(0, 10000).forEach(i -> {
executor.submit(() -> {
// 模拟I/O操作
Thread.sleep(100);
return i;
});
});
} // 自动关闭并等待所有任务完成
4. 结构化并发(Structured Concurrency)
结构化并发通过提供一个统一的API来管理多个相关任务,使并发代码更安全、更可维护:
java
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
Future<String> user = scope.fork(() -> fetchUser(userId));
Future<List<Order>> orders = scope.fork(() -> fetchOrders(userId));
// 等待所有任务完成或任一任务失败
scope.join();
// 如有任何任务失败则抛出异常
scope.throwIfFailed();
// 使用结果
processUserData(user.resultNow(), orders.resultNow());
}
5. 字符串模板(String Templates)
字符串模板是一个预览特性,允许更灵活、更高效地构建字符串:
java
String name = "James";
int age = 25;
// 基本字符串模板
String message = STR."Hello, \{name}! Next year, you'll be \{age + 1}.";
// JSON构建示例
String json = STR."""
{
"name": "\{name}",
"age": \{age},
"isActive": true,
"address": {
"city": "Shanghai",
"country": "China"
}
}
""";
6. 密封类改进(Sealed Classes)
Java 17引入的密封类在Java 21中得到完善,与模式匹配结合使用威力更大:
java
sealed interface Shape permits Circle, Rectangle, Triangle {}
record Circle(double radius) implements Shape {}
record Rectangle(double width, double height) implements Shape {}
record Triangle(double a, double b, double c) implements Shape {}
double calculateArea(Shape shape) {
return switch (shape) {
case Circle c -> Math.PI * c.radius() * c.radius();
case Rectangle r -> r.width() * r.height();
case Triangle t -> {
// 海伦公式计算面积
double s = (t.a() + t.b() + t.c()) / 2;
yield Math.sqrt(s * (s - t.a()) * (s - t.b()) * (s - t.c()));
}
};
}
7. 顺序集合(Sequenced Collections)
Java 21引入了更一致、更直观的集合API,通过新的SequencedCollection
、SequencedSet
和SequencedMap
接口提供了对集合第一个和最后一个元素的访问方法:
java
List<String> names = new ArrayList<>(List.of("Alice", "Bob", "Charlie"));
// 访问第一个和最后一个元素
String first = names.getFirst(); // "Alice"
String last = names.getLast(); // "Charlie"
// 反向视图
List<String> reversed = names.reversed(); // ["Charlie", "Bob", "Alice"]
// Map也支持类似操作
Map<Integer, String> idToName = new LinkedHashMap<>();
idToName.put(1, "Alice");
idToName.put(2, "Bob");
idToName.put(3, "Charlie");
// 获取第一个和最后一个条目
Map.Entry<Integer, String> firstEntry = idToName.firstEntry(); // 1="Alice"
Map.Entry<Integer, String> lastEntry = idToName.lastEntry(); // 3="Charlie"
8. 外部函数和内存API(Foreign Function & Memory API)
该API允许Java代码与本地代码(如C库)更安全、更高效地交互,无需使用JNI:
java
// 定义C库函数接口
MethodHandle strlen = Linker.nativeLinker().downcallHandle(
SymbolLookup.loaderLookup().lookup("strlen").orElseThrow(),
FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS)
);
// 调用本地函数
try (Arena arena = Arena.openConfined()) {
MemorySegment cString = arena.allocateUtf8String("Hello, World!");
long length = (long) strlen.invoke(cString);
System.out.println("字符串长度: " + length); // 输出: 字符串长度: 13
}
9. 向量API(Vector API)
Vector API仍处于预览状态,提供了SIMD(单指令多数据)操作的支持,可以大幅提升数值计算性能:
java
void vectorAddition(float[] a, float[] b, float[] c) {
VectorSpecies<Float> species = FloatVector.SPECIES_PREFERRED;
for (int i = 0; i < a.length; i += species.length()) {
// 计算此次迭代的向量长度
int limit = Math.min(i + species.length(), a.length);
// 创建掩码
var mask = species.maskAll(true).fromLimit(limit - i);
// 加载向量
var va = FloatVector.fromArray(species, a, i, mask);
var vb = FloatVector.fromArray(species, b, i, mask);
// 执行向量加法
var vc = va.add(vb);
// 存储结果
vc.intoArray(c, i, mask);
}
}
10. instanceof的模式匹配
虽然在Java 16中就引入了,但搭配Java 21的其他特性使用时更加强大:
java
if (obj instanceof String s && s.length() > 5) {
// 直接使用s,无需额外转换
System.out.println("长字符串: " + s);
}
结语
Java 21凭借其丰富的新特性,特别是虚拟线程和结构化并发,为Java开发带来了革命性的变化,使Java在高并发场景下更具竞争力。这些特性不仅提高了代码的表达能力,还大幅提升了开发效率和应用性能。
无论是构建微服务、Web应用还是数据处理系统,Java 21都为开发者提供了强大的工具。随着这些特性的广泛应用,我们可以期待看到更多高效、简洁且性能卓越的Java应用程序。
作为Java开发者,现在正是深入学习这些新特性并将其应用到实际项目中的好时机。希望本文能帮助你快速掌握Java 21的精华,在现代Java开发中保持竞争力!