JDK 21已经于2023年9月19日正式发布。根据发布的规划,这次发布的 JDK 21 将是一个长期支持版(LTS 版)。LTS 版每 2 年发布一个,上一次长期支持版是 21 年 9 月发布的 JDK 17。
正式稳定功能
-
JEP 431:Sequenced Collections
新增3个顺序集合接口,更清楚地表达顺序集合以及顺序集合上的操作
interface SequencedCollection<E> extends Collection<E> { SequencedCollection<E> reversed(); void addFirst(E); void addLast(E); E getFirst(); E getLast(); E removeFirst(); E removeLast(); } interface SequencedSet<E> extends Set<E>, SequencedCollection<E> { SequencedSet<E> reversed(); } interface SequencedMap<K,V> extends Map<K,V> { SequencedMap<K,V> reversed(); SequencedSet<K> sequencedKeySet(); SequencedCollection<V> sequencedValues(); SequencedSet<Entry<K,V>> sequencedEntrySet(); V putFirst(K, V); V putLast(K, V); Entry<K, V> firstEntry(); Entry<K, V> lastEntry(); Entry<K, V> pollFirstEntry(); Entry<K, V> pollLastEntry(); }
-
JEP 439:Generational ZGC
ZGC将所有对象存储在一起,Generational ZGC启用分代,更加频繁地回收新生代对象以提高性能
Generational ZGC区分于其他GC的重要理念
No multi-mapped memory Optimized barriers Double-buffered remembered sets Relocations without additional heap memory Dense heap regions Large objects Full garbage collections
-
JEP 440:Record Patterns
// As of Java 16 record Point(int x, int y) {} static void printSum(Object obj) { if (obj instanceof Point p) { int x = p.x(); int y = p.y(); System.out.println(x+y); } } // As of Java 21 static void printSum(Object obj) { if (obj instanceof Point(int x, int y)) { System.out.println(x+y); } } // 嵌套模式 static void printXCoordOfUpperLeftPointWithPatterns(Rectangle r) { if (r instanceof Rectangle(ColoredPoint(Point(var x, var y), var c), var lr)) { System.out.println("Upper-left corner: " + x); } }
-
JEP 441:Pattern Matching for switch
// 数据类型匹配 switch (data.get("key1")) { case String s -> log.info(s); case Double d -> log.info(d.toString()); case Integer i -> log.info(i.toString()); default -> log.info(""); } // 支持null static void testFooBarNew(String s) { switch (s) { case null -> System.out.println("Oops"); case "Foo", "Bar" -> System.out.println("Great"); default -> System.out.println("Ok"); } } // Case refinement static void testStringNew(String response) { switch (response) { case null -> { } case String s when s.equalsIgnoreCase("YES") -> { System.out.println("You got it"); } case String s when s.equalsIgnoreCase("NO") -> { System.out.println("Shame"); } case String s -> { System.out.println("Sorry?"); } } } ...
-
JEP 444:Virtual Threads
虚拟线程是轻量级线程,仅在 CPU 上执行计算时才消耗操作系统线程
原理类似于通过异步方式提高可扩展性,细粒度线程共享解决I/O频繁的问题
不需要被池化,每一个应用任务建一个新的虚拟线程
数量可以比操作系统线程的数量大得多,可以提供程序的吞吐量
-
JEP 449:Deprecate the Windows 32-bit x86 Port for Removal
-
JEP 451:Prepare to Disallow the Dynamic Loading of Agents
-
JEP 452:Key Encapsulation Mechanism API 公钥加密保护对称秘钥
预览阶段功能
-
JEP 430:String Templates (Preview)
String name = "Joan"; String info = STR."My name is \{name}"; assert info.equals("My name is Joan"); // true
-
JEP 442:Foreign Function & Memory API (Third Preview)
-
JEP 443:Unnamed Patterns and Variables (Preview)
Unnamed Patterns
switch (b) { case Box(RedBall _), Box(BlueBall _) -> processBox(b); case Box(GreenBall _) -> stopProcessing(); case Box(_) -> pickAnotherBox(); }
Unamed Variables
int acc = 0; for (Order _ : orders) { if (acc < LIMIT) { ... acc++ ... } } Queue<Integer> q = ... // x1, y1, z1, x2, y2, z2, ... while (q.size() >= 3) { var x = q.remove(); var y = q.remove(); var _ = q.remove(); ... new Point(x, y) ... } String s = ... try { int i = Integer.parseInt(s); ... i ... } catch (NumberFormatException _) { System.out.println("Bad number: " + s); } try (var _ = ScopedContext.acquire()) { ... no use of acquired resource ... } stream.collect(Collectors.toMap(String::toUpperCase, _ -> "NODATA"))
-
JEP 445:Unnamed Classes and Instance Main Methods (Preview)
启动类main方法更加灵活
-
具有public, protected, or default access
-
可以用空参代替String[]参数
-
可以不是static方法
启动类可以是匿名类,匿名类不能实现任何接口,不能继承除了Object的任何类,不能有任何其他地方引用
-
JEP 446:Scoped Values (Preview)
共享不可变的值,解决虚拟线程使用Thread Local可能存在的一些问题。
-
JEP 453:Structured Concurrency (Preview)
将任务构建为一系列并发子任务,将它们作为一个单元协调。子任务在它们自己的线程内独立fork或者取消,再连接成为一个单元。子任务的成功结果或者异常再由父任务聚合、处理。
Response handle() throws ExecutionException, InterruptedException { try (var scope = new StructuredTaskScope.ShutdownOnFailure()) { Supplier<String> user = scope.fork(() -> findUser()); Supplier<Integer> order = scope.fork(() -> fetchOrder()); scope.join() // Join both subtasks .throwIfFailed(); // ... and propagate errors // Here, both subtasks have succeeded, so compose their results return new Response(user.get(), order.get()); } }
优点
-
Error handling with short-circuiting: 一个子任务失败,另一个子任务取消
-
Cancellation propagation: 线程在调用之前或期间被中断,子任务都会自动取消
-
Clarity
-
Observability
孵化阶段功能
-
JEP 448:Vector API(Sixth Incubator)