Java SE 20 新增特性

科技资讯 投稿 11900 0 评论

Java SE 20 新增特性

Java SE 20 新增特性

原文地址:

CSDN:Java SE 20 新增特性

源码

镜像仓库: GitCode:java_new_features

Switch类型匹配(第四次预览

注:执行如下代码需要基于 Java SE 17 +,且增加--enable-preview参数。

package git.snippets.jdk20;


/**
 * switch类型匹配(二次预览
 *
 * @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), 范围值可以与虚拟线程很好地结合。它允许在有限的时间内存储一个值,而且只有写入该值的线程可以读取它。类似ThreadLocal对于线程的作用。详见:SCOPED VALUES IN JAVA

record 的匹配增强(第二次预览)

package git.snippets.jdk20;

/**
 * record 模式匹配增强(二次预览)
 * 需要增加 --enable-preview参数
 *
 * @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 支持类型推断,例如,定义了如下数据结构

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;
        }
    }

需要指定类型,例如:本实例需要指定 String 类型。

    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;
        }
    }

在循环中也可以支持类似的用法,示例如下:

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 中,移除了对 record 命名模式的支持,在 Java SE 19 中,如下写法是对的

        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,已经将上述写法废弃,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 的构造方法

java.net.URL的构造函数已被标记为"废弃"。应该使用URI.create(..URI.toURL(方法。下面是一个例子:

package git.snippets.jdk20;

import java.net.URI;
import java.net.URL;

/**
 * URL的构造方法被彻底废弃
 *
 * @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 {
        // 以下构造方法在 Java SE 20 被彻底废弃
        // URL url = new URL("xxx";
        // Java SE 20 用如下方法构造 URL
        URL url = URI.create("xxx".toURL(;
    }
}

更多

Java SE 7及以后各版本新增特性,持续更新中..。

参考资料

JDK 20 Release Notes

JAVA 20 FEATURES(WITH EXAMPLES

编程笔记 » Java SE 20 新增特性

赞同 (59) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽