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

相关推荐
丘山一郎4 小时前
Spring 中的IOC控制反转 和DI依赖注入
java·后端·spring
码视野4 小时前
基于 Spring Boot + Vue3 的【大学英语四六级 (CET-4/6) 作文智能评分与句式润色系统】设计与实现(含PRD/三端高保真源码/大屏)
java·前端·人工智能·spring boot·后端·vue3
MetaLite4 小时前
Spring-AOP自调用为什么失效-AopContext真能解决吗
java·后端·spring
大模型码小白4 小时前
AI 对话流性能调优:万级消息的虚拟滚动落地
java·大数据·前端·javascript·人工智能·算法·机器学习
许彰午5 小时前
14-字段级SM4加密与SM2签名
java·低代码·架构
许彰午6 小时前
13-describe元数据输出
java·低代码·架构·状态模式
用户3721574261357 小时前
Java 设置 Word 文档编辑限制并允许指定区域编辑
java
宠友信息7 小时前
社区类源码开发实践中的仿小红书系统技术要点分析
java·spring boot·redis·mysql·uni-app·vue·内容运营
用户3721574261358 小时前
Java 设置 PDF 表单域只读或扁平化
java
luteres9 小时前
Spring学习笔记
java·后端·spring