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

相关推荐
胚芽鞘6814 小时前
关于java项目中maven的理解
java·数据库·maven
岁忧5 小时前
(LeetCode 面试经典 150 题 ) 11. 盛最多水的容器 (贪心+双指针)
java·c++·算法·leetcode·面试·go
CJi0NG5 小时前
【自用】JavaSE--算法、正则表达式、异常
java
Hellyc6 小时前
用户查询优惠券之缓存击穿
java·redis·缓存
今天又在摸鱼6 小时前
Maven
java·maven
老马啸西风6 小时前
maven 发布到中央仓库常用脚本-02
java·maven
代码的余温6 小时前
MyBatis集成Logback日志全攻略
java·tomcat·mybatis·logback
一只叫煤球的猫8 小时前
【🤣离谱整活】我写了一篇程序员掉进 Java 异世界的短篇小说
java·后端·程序员
斐波娜娜8 小时前
Maven详解
java·开发语言·maven
Bug退退退1238 小时前
RabbitMQ 高级特性之事务
java·分布式·spring·rabbitmq