@@ -9,7 +9,7 @@ JDK 21 于 2023 年 9 月 19 日 发布,这是一个非常重要的版本,
99
1010JDK21 是 LTS(长期支持版),至此为止,目前有 JDK8、JDK11、JDK17 和 JDK21 这四个长期支持版了。
1111
12- JDK 21 共有 15 个新特性:
12+ JDK 21 共有 15 个新特性,这篇文章会挑选其中较为重要的一些新特性进行详细介绍 :
1313
1414- [ JEP 430:String Templates(字符串模板)] ( https://openjdk.org/jeps/430 ) (预览)
1515- [ JEP 431:Sequenced Collections(序列化集合)] ( https://openjdk.org/jeps/431 )
@@ -18,8 +18,16 @@ JDK 21 共有 15 个新特性:
1818
1919- [ JEP 440:Record Patterns(记录模式)] ( https://openjdk.org/jeps/440 )
2020
21+ - [ JEP 441:Pattern Matching for switch(switch 的模式匹配)] ( https://openjdk.org/jeps/442 )
22+
23+ - [ JEP 442:Foreign Function & Memory API(外部函数和内存 API)] ( https://openjdk.org/jeps/442 ) (第三次预览)
24+
25+ - [ JEP 443:Unnamed Patterns and Variables(未命名模式和变量] ( https://openjdk.org/jeps/443 ) (预览)
26+
2127- [ JEP 444:Virtual Threads(虚拟线程)] ( https://openjdk.org/jeps/444 )
2228
29+ - [ JEP 445:Unnamed Classes and Instance Main Methods(未命名类和实例 main 方法 )] ( https://openjdk.org/jeps/445 ) (预览)
30+
2331## JEP 430:字符串模板(预览)
2432
2533String Templates(字符串模板) 目前仍然是 JDK 21 中的一个预览功能。
@@ -119,7 +127,134 @@ String time = STR."The current time is \{
119127
120128## JEP431:序列化集合
121129
122- JDK 21 引入了一种新的集合类型:** Sequenced Collections(序列化集合)** 。
130+ JDK 21 引入了一种新的集合类型:** Sequenced Collections(序列化集合,也叫有序集合)** ,这是一种具有确定出现顺序(encounter order)的集合(无论我们遍历这样的集合多少次,元素的出现顺序始终是固定的)。序列化集合提供了处理集合的第一个和最后一个元素以及反向视图(与原始集合相反的顺序)的简单方法。
131+
132+ Sequenced Collections 包括以下三个接口:
133+
134+ - [ ` SequencedCollection ` ] ( https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/SequencedCollection.html )
135+ - [ ` SequencedSet ` ] ( https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/SequencedSet.html )
136+ - [ ` SequencedMap ` ] ( https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/SequencedMap.html )
137+
138+ ` SequencedCollection ` 接口继承了 ` Collection ` 接口, 提供了在集合两端访问、添加或删除元素以及获取集合的反向视图的方法。
139+
140+ ``` java
141+ interface SequencedCollection <E> extends Collection<E > {
142+
143+ // New Method
144+
145+ SequencedCollection<E > reversed ();
146+
147+ // Promoted methods from Deque<E>
148+
149+ void addFirst (E );
150+ void addLast (E );
151+
152+ E getFirst ();
153+ E getLast ();
154+
155+ E removeFirst ();
156+ E removeLast ();
157+ }
158+ ```
159+
160+ ` List ` 和 ` Deque ` 接口实现了` SequencedCollection ` 接口。
161+
162+ 这里以 ` ArrayList ` 为例,演示一下实际使用效果:
163+
164+ ``` java
165+ ArrayList<Integer > arrayList = new ArrayList<> ();
166+
167+ arrayList. add(1 ); // List contains: [1]
168+
169+ arrayList. addFirst(0 ); // List contains: [0, 1]
170+ arrayList. addLast(2 ); // List contains: [0, 1, 2]
171+
172+ Integer firstElement = arrayList. getFirst(); // 0
173+ Integer lastElement = arrayList. getLast(); // 2
174+
175+ List<Integer > reversed = arrayList. reversed();
176+ System . out. println(reversed); // Prints [2, 1, 0]
177+ ```
178+
179+ ` SequencedSet ` 接口直接继承了 ` SequencedCollection ` 接口并重写了 ` reversed() ` 方法。
180+
181+ ``` java
182+ interface SequencedSet <E> extends SequencedCollection<E > , Set<E > {
183+
184+ SequencedSet<E > reversed ();
185+ }
186+ ```
187+
188+ ` SortedSet ` 和 ` LinkedHashSet ` 实现了` SequencedSet ` 接口。
189+
190+ 这里以 ` LinkedHashSet ` 为例,演示一下实际使用效果:
191+
192+ ``` java
193+ LinkedHashSet<Integer > linkedHashSet = new LinkedHashSet<> (List . of(1 , 2 , 3 ));
194+
195+ Integer firstElement = linkedHashSet. getFirst(); // 1
196+ Integer lastElement = linkedHashSet. getLast(); // 3
197+
198+ linkedHashSet. addFirst(0 ); // List contains: [0, 1, 2, 3]
199+ linkedHashSet. addLast(4 ); // List contains: [0, 1, 2, 3, 4]
200+
201+ System . out. println(linkedHashSet. reversed()); // Prints [5, 3, 2, 1, 0]
202+ ```
203+
204+ ` SequencedMap ` 接口继承了 ` Map ` 接口, 提供了在集合两端访问、添加或删除键值对、获取包含 key 的 ` SequencedSet ` 、包含 value 的 ` SequencedCollection ` 、包含 entry(键值对) 的 ` SequencedSet ` 以及获取集合的反向视图的方法。
205+
206+ ``` java
207+ interface SequencedMap <K,V> extends Map<K ,V > {
208+
209+ // New Methods
210+
211+ SequencedMap<K ,V > reversed ();
212+
213+ SequencedSet<K > sequencedKeySet ();
214+ SequencedCollection<V > sequencedValues ();
215+ SequencedSet<Entry<K ,V > > sequencedEntrySet ();
216+
217+ V putFirst (K , V );
218+ V putLast (K , V );
219+
220+
221+ // Promoted Methods from NavigableMap<K, V>
222+
223+ Entry<K , V > firstEntry ();
224+ Entry<K , V > lastEntry ();
225+
226+ Entry<K , V > pollFirstEntry ();
227+ Entry<K , V > pollLastEntry ();
228+ }
229+ ```
230+
231+ ` SortedMap ` 和` LinkedHashMap ` 实现了` SequencedMap ` 接口。
232+
233+ 这里以 ` LinkedHashMap ` 为例,演示一下实际使用效果:
234+
235+ ``` java
236+ LinkedHashMap<Integer , String > map = new LinkedHashMap<> ();
237+
238+ map. put(1 , " One" );
239+ map. put(2 , " Two" );
240+ map. put(3 , " Three" );
241+
242+ map. firstEntry(); // 1=One
243+ map. lastEntry(); // 3=Three
244+
245+ System . out. println(map); // {1=One, 2=Two, 3=Three}
246+
247+ Map . Entry<Integer , String > first = map. pollFirstEntry(); // 1=One
248+ Map . Entry<Integer , String > last = map. pollLastEntry(); // 3=Three
249+
250+ System . out. println(map); // {2=Two}
251+
252+ map. putFirst(1 , " One" ); // {1=One, 2=Two}
253+ map. putLast(3 , " Three" ); // {1=One, 2=Two, 3=Three}
254+
255+ System . out. println(map); // {1=One, 2=Two, 3=Three}
256+ System . out. println(map. reversed()); // {3=Three, 2=Two, 1=One}
257+ ```
123258
124259## JEP 439:分代 ZGC
125260
@@ -144,6 +279,63 @@ java -XX:+UseZGC -XX:+ZGenerational ...
144279
145280[ Java 20 新特性概览] ( ./java20.md ) 已经详细介绍过记录模式,这里就不重复了。
146281
282+ ## JEP 441:switch 的模式匹配
283+
284+ 增强 Java 中的 switch 表达式和语句,允许在 case 标签中使用模式。当模式匹配时,执行 case 标签对应的代码。
285+
286+ 在下面的代码中,switch 表达式使用了类型模式来进行匹配。
287+
288+ ``` java
289+ static String formatterPatternSwitch(Object obj) {
290+ return switch (obj) {
291+ case Integer i - > String . format(" int %d" , i);
292+ case Long l - > String . format(" long %d" , l);
293+ case Double d - > String . format(" double %f" , d);
294+ case String s - > String . format(" String %s" , s);
295+ default - > obj. toString();
296+ };
297+ }
298+ ```
299+
300+ ## JEP 442: 外部函数和内存 API(第三次预览)
301+
302+ Java 程序可以通过该 API 与 Java 运行时之外的代码和数据进行互操作。通过高效地调用外部函数(即 JVM 之外的代码)和安全地访问外部内存(即不受 JVM 管理的内存),该 API 使 Java 程序能够调用本机库并处理本机数据,而不会像 JNI 那样危险和脆弱。
303+
304+ 外部函数和内存 API 在 Java 17 中进行了第一轮孵化,由 [ JEP 412] ( https://openjdk.java.net/jeps/412 ) 提出。Java 18 中进行了第二次孵化,由[ JEP 419] ( https://openjdk.org/jeps/419 ) 提出。Java 19 中是第一次预览,由 [ JEP 424] ( https://openjdk.org/jeps/424 ) 提出。JDK 20 中是第二次预览,由 [ JEP 434] ( https://openjdk.org/jeps/434 ) 提出。JDK 21 中是第三次预览,由 [ JEP 442] ( https://openjdk.org/jeps/442 ) 提出。
305+
306+ 在 [ Java 19 新特性概览] ( ./java19.md ) 中,我有详细介绍到外部函数和内存 API,这里就不再做额外的介绍了。
307+
308+ ## JEP 443:未命名模式和变量(预览)
309+
310+ 未命名模式和变量使得我们可以使用下划线 ` _ ` 表示未命名的变量以及模式匹配时不使用的组件,旨在提高代码的可读性和可维护性。
311+
312+ 未命名变量的典型场景是 ` try-with-resources ` 语句、 ` catch ` 子句中的异常变量和` for ` 循环。当变量不需要使用的时候就可以使用下划线 ` _ ` 代替,这样清晰标识未被使用的变量。
313+
314+ ``` java
315+ try (var _ = ScopedContext . acquire()) {
316+ // No use of acquired resource
317+ }
318+ try { ... }
319+ catch (Exception _) { ... }
320+ catch (Throwable _) { ... }
321+
322+ for (int i = 0 , _ = runOnce(); i < arr. length; i++ ) {
323+ ...
324+ }
325+ ```
326+
327+ 未命名模式是一个无条件的模式,并不绑定任何值。未命名模式变量出现在类型模式中。
328+
329+ ``` java
330+ if (r instanceof ColoredPoint(_, Color c)) { ... c ... }
331+
332+ switch (b) {
333+ case Box(RedBall _), Box(BlueBall _) - > processBox(b);
334+ case Box(GreenBall _) - > stopProcessing();
335+ case Box(_) - > pickAnotherBox();
336+ }
337+ ```
338+
147339## JEP 444:虚拟线程
148340
149341虚拟线程是一项重量级的更新,一定一定要重视!
@@ -152,6 +344,39 @@ java -XX:+UseZGC -XX:+ZGenerational ...
152344
153345[ Java 20 新特性概览] ( ./java20.md ) 已经详细介绍过虚拟线程,这里就不重复了。
154346
347+ ## JEP 445:未命名类和实例 main 方法 (预览)
348+
349+ 这个特性主要简化了 ` main ` 方法的的声明。对于 Java 初学者来说,这个 ` main ` 方法的声明引入了太多的 Java 语法概念,不利于初学者快速上手。
350+
351+ 没有使用该特性之前定义一个 ` main ` 方法:
352+
353+ ``` java
354+ public class HelloWorld {
355+ public static void main (String [] args ) {
356+ System . out. println(" Hello, World!" );
357+ }
358+ }
359+ ```
360+
361+ 使用该新特性之后定义一个 ` main ` 方法:
362+
363+ ``` java
364+ class HelloWorld {
365+ void main () {
366+ System . out. println(" Hello, World!" );
367+ }
368+ }
369+ ```
370+
371+ 进一步精简(未命名的类允许我们不定义类名):
372+
373+ ``` java
374+ void main() {
375+ System . out. println(" Hello, World!" );
376+ }
377+ ```
378+
155379## 参考
156380
157381- Java 21 String Templates:< https://howtodoinjava.com/java/java-string-templates/ >
382+ - Java 21 Sequenced Collections:https://howtodoinjava.com/java/sequenced-collections/
0 commit comments