Java SE 21 新增特性

Java SE 21 新增特性

作者:Grey

原文地址:

博客园:Java SE 21 新增特性

[CSDN:Java SE 21 新增特性](#CSDN:Java SE 21 新增特性)

源码

源仓库: Github:java_new_features

镜像仓库: GitCode:java_new_features

Record Patterns

该功能首次在 Java SE 19 中预览,在Java SE 20中发布第二次预览版,在此版本中成为永久性功能。这意味着它可以在任何为 Java SE 21 编译的程序中使用,而无需启用预览功能。

示例代码如下

java 复制代码
package git.snippets.jdk21;

/**
 * record 模式匹配增强
 * 无须增加 --enable-preview参数
 *
 * @author <a href="mailto:410486047@qq.com">Grey</a>
 * @date 2023/09/25
 * @since 21
 */
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) {
}

Switch 匹配增强

该功能首次在 Java SE 17 中预览,在在此版本中成为永久性功能。这意味着它可以在任何为 Java SE 21 编译的程序中使用,而无需启用预览功能。

java 复制代码
package git.snippets.jdk21;


/**
 * switch类型增强匹配
 * 无须增加预览参数
 *
 * @author <a href="mailto:410486047@qq.com">Grey</a>
 * @date 2023/09/25
 * @since 21
 */
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 -> {
            }
        }
    }
}

String template(预览功能)

作为本版本的预览功能推出。字符串模板是对 Java 现有字符串字面量和文本块的补充,它将字面文本与嵌入式表达式和模板处理器结合起来,从而产生专门的结果。

在 Java SE 21之前,字符串的拼接可以用下述三种方式

java 复制代码
public static void stringTestBefore21() {
        int a = 1;
        int b = 2;

        String concatenated = a + " times " + b + " = " + a * b;
        String format = String.format("%d times %d = %d", a, b, a * b);
        String formatted = "%d times %d = %d".formatted(a, b, a * b);
        System.out.println(concatenated);
        System.out.println(format);
        System.out.println(formatted);
}

Java SE 21可以用更直观的方法实现字符串的拼接

java 复制代码
 public static void stringTest21() {
        int a = 1;
        int b = 2;


        String interpolated = STR. "\{ a } times \{ b } = \{ a * b }" ;
        System.out.println(interpolated);

        String dateMessage = STR. "Today's date: \{
                LocalDate.now().format(
                        // We could also use DateTimeFormatter.ISO_DATE
                        DateTimeFormatter.ofPattern("yyyy-MM-dd")
                ) }" ;
        System.out.println(dateMessage);


        int httpStatus = 200;
        String errorMessage = "error pwd";

        String json = STR. """
    {
      "httpStatus": \{ httpStatus },
      "errorMessage": "\{ errorMessage }"
    }""" ;
        System.out.println(json);
    }

Unnamed Patterns and Variables(预览功能)

作为预览功能引入,未命名模式匹配一个记录组件,但不声明组件的名称或类型。未命名变量是可以初始化但不使用的变量,都可以使用下划线字符 (_) 来表示它们。

例如:

java 复制代码
   try {
            int number = Integer.parseInt(string);
        } catch (NumberFormatException e) {
            System.err.println("Not a number");
        }

其中 e 是未使用的变量,可以写成

java 复制代码
   try {
            int number = Integer.parseInt(string);
        } catch (NumberFormatException _) {
            System.err.println("Not a number");
        }

再如

java 复制代码
        Object object = null;
        if (object instanceof Points(int x, int y)) {
            System.out.println("object is a position, x = " + x);
        }

其中 y 是未使用的变量,可以写成

java 复制代码
        Object object = null;
        if (object instanceof Points(int x, int _)) {
            System.out.println("object is a position, x = " + x);
        }

switch 表达式中也可以有类似的用法,例如

java 复制代码
        Object obj = null;
        switch (obj) {
            case Byte    b -> System.out.println("Integer number");
            case Short   s -> System.out.println("Integer number");
            case Integer i -> System.out.println("Integer number");
            case Long    l -> System.out.println("Integer number");

            case Float  f -> System.out.println("Floating point number");
            case Double d -> System.out.println("Floating point number");

            default -> System.out.println("Not a number");
        }

也可以写成

java 复制代码
Object obj = null;
        switch (obj) {
            case Byte    _ -> System.out.println("Integer number");
            case Short   _ -> System.out.println("Integer number");
            case Integer _ -> System.out.println("Integer number");
            case Long    _ -> System.out.println("Integer number");

            case Float  _ -> System.out.println("Floating point number");
            case Double _ -> System.out.println("Floating point number");

            default -> System.out.println("Not a number");
        }

Unnamed Classes and Instance Main Methods (预览功能)

预览功能,简言之,就是main方法可以更加精简,原先写一个 Hello World 需要这样做

java 复制代码
public class UnnamedClassesAndInstanceMainMethodsTest {
    public static void main(String[] args) {
        System.out.println("hello world");
    }
}

现在可以简化成

java 复制代码
public class UnnamedClassesAndInstanceMainMethodsTest {

    void main() {
        System.out.println("hello world");
    }

}

注:上述代码需要在命令行运行,目前IDE还不支持,在命令行下执行:

cmd 复制代码
java --enable-preview --source 21 UnnamedClassesAndInstanceMainMethodsTest.java

输出:hello world

更多

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

参考资料

Java Language Changes for Java SE 21

JDK 21 Release Notes

JAVA 21 FEATURES(WITH EXAMPLES

相关推荐
ps酷教程1 小时前
Jackson 解决没有无参构造函数的反序列化问题
java
NiceCloud喜云1 小时前
Opus 4.8 的 Effort Control 怎么选:Low 到 Max 五档策略
android·java·大数据·前端·c++·python·spring
_日拱一卒2 小时前
LeetCode:994腐烂的橘子
java·数据结构·算法·leetcode·深度优先
隔窗听雨眠2 小时前
Nginx网关响应慢排查手记
java·服务器·nginx
智慧物业老杨3 小时前
智慧物业合同周期管理系统:从风险预警到智能交接的全流程数智化落地方案
java·人工智能·python
源码宝3 小时前
MES系统源码:Java8 + SpringBoot2.7 + MySQL8 + Redis,后端源码清爽易扩展
java·后端·源码·springboot·mes系统·源码二开·mes源码
JAVA社区3 小时前
Java高级全套教程(十)—— SpringCloudAlibaba超详细实战详解
java·开发语言·spring cloud·面试·职场和发展
金銀銅鐵4 小时前
[Java] 如何理解 class 文件中方法的 descriptor?
java·后端
云烟成雨TD4 小时前
Spring AI Alibaba 1.x 系列【63】AI Agent 长期记忆
java·人工智能·spring
憧憬成为java架构高手的小白4 小时前
苍穹外卖--day09
java·spring boot·百度