---
title: Java 20 æ°ç¹æ§æ¦è§
category: Java
tag:
- Javaæ°ç¹æ§
---
JDK 20 äº 2023 å¹´ 3 æ 21 æ¥åå¸ï¼éé¿ææ¯æçæ¬ã
æ ¹æ®å¼å计åï¼ä¸ä¸ä¸ª LTS çæ¬å°±æ¯å°äº 2023 å¹´ 9 æåå¸ç JDK 21ã

JDK 20 åªæ 7 个æ°ç¹æ§ï¼
- [JEP 429ï¼Scoped Valuesï¼ä½ç¨åå¼ï¼](https://openjdk.org/jeps/429)ï¼ç¬¬ä¸æ¬¡åµåï¼
- [JEP 432ï¼Record Patternsï¼è®°å½æ¨¡å¼ï¼](https://openjdk.org/jeps/432)ï¼ç¬¬äºæ¬¡é¢è§ï¼
- [JEP 433ï¼switch 模å¼å¹é
](https://openjdk.org/jeps/433)ï¼ç¬¬å次é¢è§ï¼
- [JEP 434: Foreign Function & Memory APIï¼å¤é¨å½æ°åå
å APIï¼](https://openjdk.org/jeps/434)ï¼ç¬¬äºæ¬¡é¢è§ï¼
- [JEP 436: Virtual Threadsï¼èæçº¿ç¨ï¼](https://openjdk.org/jeps/436)ï¼ç¬¬äºæ¬¡é¢è§ï¼
- [JEP 437:Structured Concurrencyï¼ç»æåå¹¶åï¼](https://openjdk.org/jeps/437)(ç¬¬äºæ¬¡åµå)
- [JEP 432:åé APIï¼](https://openjdk.org/jeps/438)ç¬¬äºæ¬¡åµåï¼
## JEP 429ï¼ä½ç¨åå¼ï¼ç¬¬ä¸æ¬¡åµåï¼
ä½ç¨åå¼ï¼Scoped Valuesï¼å®å¯ä»¥å¨çº¿ç¨å
å线ç¨é´å
±äº«ä¸å¯åçæ°æ®ï¼ä¼äºçº¿ç¨å±é¨åéï¼å°¤å
¶æ¯å¨ä½¿ç¨å¤§éèæçº¿ç¨æ¶ã
```java
final static ScopedValue<...> V = new ScopedValue<>();
// In some method
ScopedValue.where(V, )
.run(() -> { ... V.get() ... call methods ... });
// In a method called directly or indirectly from the lambda expression
... V.get() ...
```
ä½ç¨åå¼å
许å¨å¤§åç¨åºä¸çç»ä»¶ä¹é´å®å
¨ææå°å
±äº«æ°æ®ï¼èæ éæ±å©äºæ¹æ³åæ°ã
å
³äºä½ç¨åå¼ç详ç»ä»ç»ï¼æ¨èé
读[ä½ç¨åå¼å¸¸è§é®é¢è§£ç](https://www.happycoders.eu/java/scoped-values/)è¿ç¯æç« ã
## JEP 432ï¼è®°å½æ¨¡å¼ï¼ç¬¬äºæ¬¡é¢è§ï¼
è®°å½æ¨¡å¼ï¼Record Patternsï¼ å¯å¯¹ record çå¼è¿è¡è§£æï¼ä¹å°±æ¯æ´æ¹ä¾¿å°ä»è®°å½ç±»ï¼Record Classï¼ä¸æåæ°æ®ãå¹¶ä¸ï¼è¿å¯ä»¥åµå¥è®°å½æ¨¡å¼åç±»åæ¨¡å¼ç»å使ç¨ï¼ä»¥å®ç°å¼ºå¤§çãå£°ææ§çåå¯ç»åçæ°æ®å¯¼èªåå¤çå½¢å¼ã
è®°å½æ¨¡å¼ä¸è½åç¬ä½¿ç¨ï¼èæ¯è¦ä¸ instanceof æ switch 模å¼å¹é
ä¸å使ç¨ã
å
以 instanceof 为ä¾ç®åæ¼ç¤ºä¸ä¸ã
ç®åå®ä¹ä¸ä¸ªè®°å½ç±»ï¼
```java
record Shape(String type, long unit){}
```
没æè®°å½æ¨¡å¼ä¹åï¼
```java
Shape circle = new Shape("Circle", 10);
if (circle instanceof Shape shape) {
System.out.println("Area of " + shape.type() + " is : " + Math.PI * Math.pow(shape.unit(), 2));
}
```
æäºè®°å½æ¨¡å¼ä¹åï¼
```java
Shape circle = new Shape("Circle", 10);
if (circle instanceof Shape(String type, long unit)) {
System.out.println("Area of " + type + " is : " + Math.PI * Math.pow(unit, 2));
}
```
åççè®°å½æ¨¡å¼ä¸ switch çé
å使ç¨ã
å®ä¹ä¸äºç±»ï¼
```java
interface Shape {}
record Circle(double radius) implements Shape { }
record Square(double side) implements Shape { }
record Rectangle(double length, double width) implements Shape { }
```
没æè®°å½æ¨¡å¼ä¹åï¼
```java
Shape shape = new Circle(10);
switch (shape) {
case Circle c:
System.out.println("The shape is Circle with area: " + Math.PI * c.radius() * c.radius());
break;
case Square s:
System.out.println("The shape is Square with area: " + s.side() * s.side());
break;
case Rectangle r:
System.out.println("The shape is Rectangle with area: + " + r.length() * r.width());
break;
default:
System.out.println("Unknown Shape");
break;
}
```
æäºè®°å½æ¨¡å¼ä¹åï¼
```java
Shape shape = new Circle(10);
switch(shape) {
case Circle(double radius):
System.out.println("The shape is Circle with area: " + Math.PI * radius * radius);
break;
case Square(double side):
System.out.println("The shape is Square with area: " + side * side);
break;
case Rectangle(double length, double width):
System.out.println("The shape is Rectangle with area: + " + length * width);
break;
default:
System.out.println("Unknown Shape");
break;
}
```
è®°å½æ¨¡å¼å¯ä»¥é¿å
ä¸å¿
è¦ç转æ¢ï¼ä½¿å¾ä»£ç æ´å»ºç®æ´æè¯»ãèä¸ï¼ç¨äºè®°å½æ¨¡å¼åä¸å¿
åæ
å¿ `null` æè
`NullPointerException`ï¼ä»£ç æ´å®å
¨å¯é ã
è®°å½æ¨¡å¼å¨ Java 19 è¿è¡äºç¬¬ä¸æ¬¡é¢è§ï¼ ç± [JEP 405](https://openjdk.org/jeps/405) æåºãJDK 20 䏿¯ç¬¬äºæ¬¡é¢è§ï¼ç± [JEP 432](https://openjdk.org/jeps/432) æåºãè¿æ¬¡çæ¹è¿å
æ¬ï¼
- æ·»å 对éç¨è®°å½æ¨¡å¼ç±»ååæ°æ¨æçæ¯æï¼
- æ·»å å¯¹è®°å½æ¨¡å¼çæ¯æä»¥åºç°å¨å¢å¼ºè¯å¥çæ é¢ä¸`for`
- å é¤å¯¹å½åè®°å½æ¨¡å¼çæ¯æã
**注æ**ï¼ä¸è¦æè®°å½æ¨¡å¼å [JDK16](./java16.md) æ£å¼å¼å
¥çè®°å½ç±»ææ··äºã
## JEP 433ï¼switch 模å¼å¹é
ï¼ç¬¬å次é¢è§ï¼
æ£å¦ `instanceof` 䏿 ·ï¼ `switch` ä¹ç´§è·çå¢å äºç±»åå¹é
èªå¨è½¬æ¢åè½ã
`instanceof` 代ç 示ä¾ï¼
```java
// Old code
if (o instanceof String) {
String s = (String)o;
... use s ...
}
// New code
if (o instanceof String s) {
... use s ...
}
```
`switch` 代ç 示ä¾ï¼
```java
// Old code
static String formatter(Object o) {
String formatted = "unknown";
if (o instanceof Integer i) {
formatted = String.format("int %d", i);
} else if (o instanceof Long l) {
formatted = String.format("long %d", l);
} else if (o instanceof Double d) {
formatted = String.format("double %f", d);
} else if (o instanceof String s) {
formatted = String.format("String %s", s);
}
return formatted;
}
// New code
static String formatterPatternSwitch(Object o) {
return switch (o) {
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 -> o.toString();
};
}
```
`switch` 模å¼å¹é
åå«å¨ Java17ãJava18ãJava19 ä¸è¿è¡äºé¢è§ï¼Java20 æ¯ç¬¬å次é¢è§äºãæ¯ä¸æ¬¡çé¢è§åºæ¬é½ä¼æä¸äºå°æ¹è¿ï¼è¿éå°±ä¸ç»æäºã
## JEP 434: å¤é¨å½æ°åå
å APIï¼ç¬¬äºæ¬¡é¢è§ï¼
Java ç¨åºå¯ä»¥éè¿è¯¥ API ä¸ Java è¿è¡æ¶ä¹å¤ç代ç åæ°æ®è¿è¡äºæä½ãéè¿é«æå°è°ç¨å¤é¨å½æ°ï¼å³ JVM ä¹å¤ç代ç ï¼åå®å
¨å°è®¿é®å¤é¨å
åï¼å³ä¸å JVM 管ççå
åï¼ï¼è¯¥ API 使 Java ç¨åºè½å¤è°ç¨æ¬æºåºå¹¶å¤çæ¬æºæ°æ®ï¼èä¸ä¼å JNI 飿 ·å±é©åèå¼±ã
å¤é¨å½æ°åå
å 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) æåºï¼è¿æ¬¡çæ¹è¿å
æ¬ï¼
- `MemorySegment` å `MemoryAddress` æ½è±¡çç»ä¸
- å¢å¼ºç `MemoryLayout` 屿¬¡ç»æ
- `MemorySession`æå为`Arena`å`SegmentScope`ï¼ä»¥ä¿è¿è·¨ç»´æ¤è¾¹ççæ®µå
±äº«ã
å¨ [Java 19 æ°ç¹æ§æ¦è§](./java19.md) ä¸ï¼ææè¯¦ç»ä»ç»å°å¤é¨å½æ°åå
å APIï¼è¿éå°±ä¸ååé¢å¤çä»ç»äºã
## JEP 436: èæçº¿ç¨ï¼ç¬¬äºæ¬¡é¢è§ï¼
èæçº¿ç¨ï¼Virtual Threadï¼æ¯ JDK è䏿¯ OS å®ç°çè½»é级线ç¨(Lightweight Processï¼LWPï¼ï¼ç± JVM è°åº¦ã许å¤èæçº¿ç¨å
±äº«åä¸ä¸ªæä½ç³»ç»çº¿ç¨ï¼èæçº¿ç¨çæ°éå¯ä»¥è¿å¤§äºæä½ç³»ç»çº¿ç¨çæ°éã
å¨å¼å
¥èæçº¿ç¨ä¹åï¼`java.lang.Thread` å
å·²ç»æ¯ææè°çå¹³å°çº¿ç¨ï¼ä¹å°±æ¯æ²¡æèæçº¿ç¨ä¹åï¼æä»¬ä¸ç´ä½¿ç¨ç线ç¨ãJVM è°åº¦ç¨åºéè¿å¹³å°çº¿ç¨ï¼è½½ä½çº¿ç¨ï¼æ¥ç®¡çèæçº¿ç¨ï¼ä¸ä¸ªå¹³å°çº¿ç¨å¯ä»¥å¨ä¸åçæ¶é´æ§è¡ä¸åçèæçº¿ç¨ï¼å¤ä¸ªèæçº¿ç¨æè½½å¨ä¸ä¸ªå¹³å°çº¿ç¨ä¸ï¼ï¼å½èæçº¿ç¨è¢«é»å¡æçå¾
æ¶ï¼å¹³å°çº¿ç¨å¯ä»¥åæ¢å°æ§è¡å¦ä¸ä¸ªèæçº¿ç¨ã
èæçº¿ç¨ãå¹³å°çº¿ç¨åç³»ç»å
æ ¸çº¿ç¨çå
³ç³»å¾å¦ä¸æç¤ºï¼å¾æºï¼[How to Use Java 19 Virtual Threads](https://medium.com/javarevisited/how-to-use-java-19-virtual-threads-c16a32bad5f7)ï¼ï¼

å
³äºå¹³å°çº¿ç¨åç³»ç»å
æ ¸çº¿ç¨ç对åºå
³ç³»å¤æä¸ç¹ï¼å¨ Windows å Linux çä¸»æµæä½ç³»ç»ä¸ï¼Java 线ç¨éç¨çæ¯ä¸å¯¹ä¸ççº¿ç¨æ¨¡åï¼ä¹å°±æ¯ä¸ä¸ªå¹³å°çº¿ç¨å¯¹åºä¸ä¸ªç³»ç»å
æ ¸çº¿ç¨ãSolaris ç³»ç»æ¯ä¸ä¸ªç¹ä¾ï¼HotSpot VM å¨ Solaris 䏿¯æå¤å¯¹å¤åä¸å¯¹ä¸ãå
·ä½å¯ä»¥åè R 大çåç: [JVM ä¸ççº¿ç¨æ¨¡åæ¯ç¨æ·çº§çä¹ï¼](https://www.zhihu.com/question/23096638/answer/29617153)ã
ç¸æ¯è¾äºå¹³å°çº¿ç¨æ¥è¯´ï¼èæçº¿ç¨æ¯å»ä»·ä¸è½»é级çï¼ä½¿ç¨å®åç«å³è¢«éæ¯ï¼å æ¤å®ä»¬ä¸éè¦è¢«éç¨ææ± åï¼æ¯ä¸ªä»»å¡å¯ä»¥æèªå·±ä¸å±çèæçº¿ç¨æ¥è¿è¡ãèæçº¿ç¨æå忢夿¥å®ç°çº¿ç¨ä¹é´ç忢ï¼é¿å
äºä¸ä¸æåæ¢çé¢å¤èè´¹ï¼å
¼é¡¾äºå¤çº¿ç¨çä¼ç¹ï¼ç®åäºé«å¹¶åç¨åºç夿ï¼å¯ä»¥ææåå°ç¼åãç»´æ¤åè§å¯é«ååéå¹¶ååºç¨ç¨åºçå·¥ä½éã
èæçº¿ç¨å¨å
¶ä»å¤çº¿ç¨è¯è¨ä¸å·²ç»è¢«è¯å®æ¯ååæç¨çï¼æ¯å¦ Go ä¸ç GoroutineãErlang ä¸çè¿ç¨ã
ç¥ä¹æä¸ä¸ªå
³äº Java 19 èæçº¿ç¨çè®¨è®ºï¼æå
´è¶£çå¯ä»¥å»ççï¼ ã
Java èæçº¿ç¨ç详ç»è§£è¯»ååçå¯ä»¥çä¸é¢è¿å ç¯æç« ï¼
- [èæçº¿ç¨æç®å
¥é¨](https://javaguide.cn/java/concurrent/virtual-thread.html)
- [Java19 æ£å¼ GAï¼çèæçº¿ç¨å¦ä½å¤§å¹
æé«ç³»ç»ååé](https://mp.weixin.qq.com/s/yyApBXxpXxVwttr01Hld6Q)
- [èæçº¿ç¨ - VirtualThread æºç éè§](https://www.cnblogs.com/throwable/p/16758997.html)
èæçº¿ç¨å¨ Java 19 ä¸è¿è¡äºç¬¬ä¸æ¬¡é¢è§ï¼ç±[JEP 425](https://openjdk.org/jeps/425)æåºãJDK 20 䏿¯ç¬¬äºæ¬¡é¢è§ï¼åäºä¸äºç»å¾®ååï¼è¿éå°±ä¸ç»æäºã
æåï¼æä»¬æ¥çä¸ä¸åç§å建èæçº¿ç¨çæ¹æ³ï¼
```java
// 1ãéè¿ Thread.ofVirtual() å建
Runnable fn = () -> {
// your code here
};
Thread thread = Thread.ofVirtual(fn)
.start();
// 2ãéè¿ Thread.startVirtualThread() ãå建
Thread thread = Thread.startVirtualThread(() -> {
// your code here
});
// 3ãéè¿ Executors.newVirtualThreadPerTaskExecutor() å建
var executorService = Executors.newVirtualThreadPerTaskExecutor();
executorService.submit(() -> {
// your code here
});
class CustomThread implements Runnable {
@Override
public void run() {
System.out.println("CustomThread run");
}
}
//4ãéè¿ ThreadFactory å建
CustomThread customThread = new CustomThread();
// è·å线ç¨å·¥åç±»
ThreadFactory factory = Thread.ofVirtual().factory();
// å建èæçº¿ç¨
Thread thread = factory.newThread(customThread);
// å¯å¨çº¿ç¨
thread.start();
```
éè¿ä¸è¿°å举ç 4 ç§å建èæçº¿ç¨çæ¹å¼å¯ä»¥çåºï¼å®æ¹ä¸ºäºéä½èæçº¿ç¨ç鍿§ï¼å°½åå¤ç¨åæç `Thread` 线ç¨ç±»ï¼è¿æ ·å¯ä»¥å¹³æ»çè¿æ¸¡å°èæçº¿ç¨ç使ç¨ã
## JEP 437: ç»æåå¹¶å(ç¬¬äºæ¬¡åµå)
Java 19 å¼å
¥äºç»æåå¹¶åï¼ä¸ç§å¤çº¿ç¨ç¼ç¨æ¹æ³ï¼ç®çæ¯ä¸ºäºéè¿ç»æåå¹¶å API æ¥ç®åå¤çº¿ç¨ç¼ç¨ï¼å¹¶ä¸æ¯ä¸ºäºå代`java.util.concurrent`ï¼ç®åå¤äºåµåå¨é¶æ®µã
ç»æåå¹¶åå°ä¸å线ç¨ä¸è¿è¡çå¤ä¸ªä»»å¡è§ä¸ºå个工ä½åå
ï¼ä»èç®åé误å¤çãæé«å¯é æ§å¹¶å¢å¼ºå¯è§å¯æ§ãä¹å°±æ¯è¯´ï¼ç»æåå¹¶åä¿çäºå线ç¨ä»£ç çå¯è¯»æ§ãå¯ç»´æ¤æ§åå¯è§å¯æ§ã
ç»æåå¹¶åçåºæ¬ API æ¯[`StructuredTaskScope`](https://download.java.net/java/early_access/loom/docs/api/jdk.incubator.concurrent/jdk/incubator/concurrent/StructuredTaskScope.html)ã`StructuredTaskScope` æ¯æå°ä»»å¡æå为å¤ä¸ªå¹¶ååä»»å¡ï¼å¨å®ä»¬èªå·±ç线ç¨ä¸æ§è¡ï¼å¹¶ä¸åä»»å¡å¿
é¡»å¨ä¸»ä»»å¡ç»§ç»ä¹å宿ã
`StructuredTaskScope` çåºæ¬ç¨æ³å¦ä¸ï¼
```java
try (var scope = new StructuredTaskScope