Java SE 20 新增特性
作者:Grey
原文地址:
博客園:Java SE 20 新增特性
CSDN:Java SE 20 新增特性
源碼
源倉庫: Github:java_new_features
鏡像倉庫: GitCode:java_new_features
Switch類型匹配(第四次預(yù)覽)
在Java SE 17 新增特性中,Switch 類型匹配作為預(yù)覽功能推出,到 Java SE 20 ,這個(gè)功能已經(jīng)是第四次預(yù)覽版,在 Java SE 17 中,可以通過加強(qiáng) switch 表達(dá)式和語句的模式匹配能力,減少了定義這些表達(dá)式所需的模板,此外,switch 中增加了空值的支持。如下示例:
注:執(zhí)行如下代碼需要基于 Java SE 17 + ,且增加--enable-preview
參數(shù)。
package git.snippets.jdk20;
/**
* switch類型匹配(二次預(yù)覽)
*
* @author <a href="mailto:410486047@qq.com">Grey</a>
* @date 2023/05/03
* @since 20
*/
public class SwitchMatchTest {
public static void main(String[] args) {
switchMatch(3);
switchMatch("HELLO");
switchMatch("hello world");
switchMatch(null);
}
static void switchMatch(Object obj) {
switch (obj) {
case String s when s.length() > 5 -> System.out.println(s.toUpperCase());
case String s -> System.out.println(s.toLowerCase());
case Integer i -> System.out.println(i * i);
case null -> System.out.println("null obj");
default -> {
}
}
}
}
范圍值(Scoped Value,孵化階段)
JEP 429 在 Java SE 20 的孵化階段引入了范圍值(ScopedValue), 范圍值可以與虛擬線程很好地結(jié)合。它允許在有限的時(shí)間內(nèi)存儲(chǔ)一個(gè)值,而且只有寫入該值的線程可以讀取它。類似ThreadLocal對(duì)于線程的作用。詳見:SCOPED VALUES IN JAVA
record 的匹配增強(qiáng)(第二次預(yù)覽)
record 的匹配增強(qiáng)首次預(yù)覽在 Java SE 19, record 可以與 instanceof 一起使用,也可以使用 switch 來訪問記錄的字段,而無需強(qiáng)制轉(zhuǎn)換和調(diào)用訪問器方法,一個(gè) record 的示例如下
package git.snippets.jdk20;
/**
* record 模式匹配增強(qiáng)(二次預(yù)覽)
* 需要增加 --enable-preview參數(shù)
*
* @author <a href="mailto:410486047@qq.com">Grey</a>
* @date 2022/9/22
* @since 19
*/
public class RecordTest {
public static void main(String[] args) {
Points points = new Points(1, 2);
Line line = new Line(new Points(1, 2), new Points(3, 4));
printPoints(points);
printLine(line);
}
private static void printPoints(Object object) {
if (object instanceof Points(int x, int y)) {
System.out.println("jdk 19 object is a position, x = " + x + ", y = " + y);
}
if (object instanceof Points points) {
System.out.println("pre jdk 19 object is a position, x = " + points.x()
+ ", y = " + points.y());
}
switch (object) {
case Points position -> System.out.println("pre jdk 19 object is a position, x = " + position.x()
+ ", y = " + position.y());
default -> throw new IllegalStateException("Unexpected value: " + object);
}
switch (object) {
case Points(int x, int y) -> System.out.println(" jdk 19 object is a position, x = " + x
+ ", y = " + y);
default -> throw new IllegalStateException("Unexpected value: " + object);
}
}
public static void printLine(Object object) {
if (object instanceof Line(Points(int x1, int y1), Points(int x2, int y2))) {
System.out.println("object is a path, x1 = " + x1 + ", y1 = " + y1
+ ", x2 = " + x2 + ", y2 = " + y2);
}
switch (object) {
case Line(Points(int x1, int y1), Points(int x2, int y2)) ->
System.out.println("object is a path, x1 = " + x1 + ", y1 = " + y1
+ ", x2 = " + x2 + ", y2 = " + y2);
// other cases ...
default -> throw new IllegalStateException("Unexpected value: " + object);
}
}
}
record Points(int x, int y) {
}
record Line(Points from, Points to) {
}
此外,在 JEP 432 中,Java SE 20 的 record 支持類型推斷,例如,定義了如下數(shù)據(jù)結(jié)構(gòu)
interface Multi<T> {}
record Tuple<T>(T t1, T t2) implements Multi<T> {}
record Triple<T>(T t1, T t2, T t3) implements Multi<T> {}
在 Java SE 20 之前,需要這樣做
// 需要指定類型
static void preJDK20(Multi<String> multi) {
if (multi instanceof Tuple<String>(var s1, var s2)) {
System.out.println("Tuple: " + s1 + ", " + s2);
} else if (multi instanceof Triple<String>(var s1, var s2, var s3)) {
System.out.println("Triple: " + s1 + ", " + s2 + ", " + s3);
}
}
需要指定類型,例如:本實(shí)例需要指定 String 類型。
到了 Java SE 20,record 有類型推斷,所以上述代碼可以寫成
static void JDK20(Multi<String> multi) {
if (multi instanceof Tuple(var s1, var s2)) {
System.out.println("Tuple: " + s1 + ", " + s2);
} else if (multi instanceof Triple(var s1, var s2, var s3)) {
System.out.println("Triple: " + s1 + ", " + s2 + ", " + s3);
}
}
在循環(huán)中也可以支持類似的用法,示例如下:
在 Java SE 20 之前
record Position(int x, int y) {
}
static void preJDK20Loop(List<Position> positions) {
for (Position p : positions) {
System.out.printf("(%d, %d)%n", p.x(), p.y());
}
}
在 Java SE 20 版本中,可直接寫成如下形式
static void JDK20Loop(List<Position> positions) {
for (Position(int x, int y) : positions) {
System.out.printf("(%d, %d)%n", x, y);
}
}
此外,在 Java SE 20 中,移除了對(duì) record 命名模式的支持,在 Java SE 19 中,如下寫法是對(duì)的
if (object instanceof Points(int x, int y) points) {
System.out.println("pre jdk 19 object is a position, x = " + points.x()
+ ", y = " + points.y());
}
但是到了 Java SE 20 ,已經(jīng)將上述寫法廢棄,Java SE 20 只支持如下兩種寫法
if (object instanceof Points(int x, int y)) {
System.out.println("jdk 19 object is a position, x = " + x + ", y = " + y);
}
if (object instanceof Points points) {
System.out.println("pre jdk 19 object is a position, x = " + points.x()
+ ", y = " + points.y());
}
廢棄 java.net.URL 的構(gòu)造方法
java.net.URL
的構(gòu)造函數(shù)已被標(biāo)記為"廢棄"。應(yīng)該使用URI.create(..)
和URI.toURL()
方法。下面是一個(gè)例子:
package git.snippets.jdk20;
import java.net.URI;
import java.net.URL;
/**
* URL的構(gòu)造方法被徹底廢棄
*
* @author <a href="mailto:410486047@qq.com">Grey</a>
* @date 2023/05/03
* @since 20
*/
public class URLConstructorTest {
public static void main(String[] args) throws Exception {
// 以下構(gòu)造方法在 Java SE 20 被徹底廢棄
// URL url = new URL("xxx");
// Java SE 20 用如下方法構(gòu)造 URL
URL url = URI.create("xxx").toURL();
}
}
更多
Java SE 7及以后各版本新增特性,持續(xù)更新中...
參考資料
Java Language Changes for Java SE 20
JDK 20 Release Notes文章來源:http://www.zghlxwxcb.cn/news/detail-432663.html
JAVA 20 FEATURES(WITH EXAMPLES)文章來源地址http://www.zghlxwxcb.cn/news/detail-432663.html
到了這里,關(guān)于Java SE 20 新增特性的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!