Java21 新特性

news2024/11/29 1:42:53

文章目录

    • 1. 概述
    • 2. JDK21 安装与配置
    • 3. 新特性
      • 3.1 switch模式匹配
      • 3.2 字符串模板
      • 3.3 顺序集合
      • 3.4 记录模式(Record Patterns)
      • 3.5 未命名类和实例的main方法(预览版)
      • 3.6 虚拟线程

1. 概述


image-20230928232939153

2023年9月19日 ,Oracle 发布了 JDK21,是自 JDK17 之后最新的 LTS 版本(long-term support,长期支持版)。LTS版本一般每两年发布一个,JDK目前的LTS版本有:JDK8 , JDK11 , JDK17 ,JDK21。

Java21新特性:( oracle jdk、openjdk文档)

  • 字符串模板(预览版)
  • 虚拟线程(在JDK19中是预览版,在JDK21中是正式版,会大大改变多线程的编程风格和解决问题的方式)
  • 顺序集合(JDK21引入了SequencedCollection、SequencedSet 、SequencedMap 接口,这些接口提供了在集合开头或结尾处添加、修改或删除元素的方法,以及反转集合的功能)
  • 分代ZGC(属于JVM层面的功能)
  • 记录模式
  • switch的模式匹配
  • 未命名模式和变量(预览版)
  • 未命名类和实例的main方法(预览版)
  • 作用域值(预览版)
  • 矢量API(第六个孵化器)
  • 弃用Windows32位x86端口
  • 禁止代理的动态加载
  • 密钥封装机制的API(引入密钥封装机制 (KEM) 的 API,是一种使用公钥加密来保护对称密钥的加密技术)
  • 结构化并发(预览版, 简化并发编程)
  • 外部函数与内存API(第三次预览版)

2. JDK21 安装与配置


Oracle JDK21 官网下载地址:https://www.oracle.com/java/technologies/downloads/#java21

1、下载 windows 版 oracle jdk,下载地址:https://download.oracle.com/java/21/latest/jdk-21_windows-x64_bin.exe

image-20230928215820796

2、双击刚刚下载好的jdk安装包,进行安装:

image-20230928220157286

image-20230928220338493

image-20230928220503653

3、配置环境变量,在系统变量path中创建新的变量值,变量值的内容就是dk21的安装位置:(偷懒了😈)

系统变量变量值
PathD:\Program Files\Environment\Java\jdk-21

3. 新特性


3.1 switch模式匹配

在Java8中switch可以处理的数据类型有:byte、short、char、int、String、Enum。

而在Java21中switch可以处理更多的类型,会根据类型进行匹配,switch增强版语法如下:

switch(object){
   case 普通类型 变量名 [when 条件] -> ...; //通过when关键字可以进行条件筛选,[]表示可选语法     
   case record 类型 变量名 -> ...; // record 记录
   case enum 类型 变量名 -> ...;
   case null -> ...;
   case default -> ...;
}

示例:

package cn.z3inc.jdk21;

import java.time.LocalDate;

/**
 * switch 模式匹配
 *
 * @author 白豆五
 * @date 2023/9/29
 * @since JDK21
 */
public class SwitchTest {
    public static void main(String[] args) {
        test1(new A("HUAWEI Mate 60 Pro"));
        test2(new B("遥遥领先"));
        test2(null);
        test3();
    }

    /**
     * 根据不同的类型去做不同的事情 (jdk21之前的写法)
     *
     * @param obj 入参的类型
     */
    static void test1(Object obj) {
        if (obj instanceof A a) { //instanceof 的模式匹配(Java14的新语法,老版本需要强转)
            System.out.println("类型A===" + a.name);
        } else if (obj instanceof B b) {
            System.out.println("类型B===" + b.title);
        }
    }

    /**
     * 根据不同的类型去做不同的事情 (jdk21:switch的新语法)
     *
     * @param obj 入参的类型
     */
    static void test2(Object obj) {
        switch (obj) {
            //  case 数据类型 变量名 -> 表达式;
            case A a -> System.out.println("类型A===" + a.name);
            case B b -> System.out.println("类型B===" + b.title);
            // case null -> System.out.println("null");
            // default -> System.out.println("其他类型");
            case null, default -> System.out.println("其他类型或null"); // 合并写法
        }
    }

    // 静态内部类A
    static class A {
        String name;

        public A(String name) {
            this.name = name;
        }
    }

    // 静态内部类B
    static class B {
        String title;

        public B(String title) {
            this.title = title;
        }
    }

    /**
     * 输出当前日期格式为"yyyy-MM-dd"
     */
    static void test3() {
        LocalDate date = LocalDate.now();
        System.out.println("date = " + date);
        String formatted = switch (date.getDayOfWeek()) {
            case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> "工作日";
            case SATURDAY, SUNDAY -> "周末";
        };
        System.out.println(formatted);
    }
}

image-20230929165020274


3.2 字符串模板

在Java21之前拼接字符串的写法如下:

方式1:使用 + 拼接字符串

String x = "world"String s = "hello" + x + "Java21!";

方式2:使用StringBuilder拼接字符串

String s = new StringBuilder()
                  .append("Hello")
                  .append(" ")
                  .append("World!")
                  .toString();

方式3:使用String的format()或formatted()方法,格式化字符串(有点像c语言的写法)

String name = "旺财";
int age = 18;
char sex = '男';
// 1. String.format():用于格式化字符串
// 参数1: 一个字符串模板 里面包含占位符%xxx"
// 参数2: 替换的值 可变参数
String s = String.format("姓名 %s,年龄 %d,性别 %c", name, age, sex);
System.out.println(s); // 姓名 旺财,年龄 18,性别 男

// 2. String.formatted()是Java15新特性,与String.format()功能一样
s = "姓名 %s,年龄 %d,性别 %c".formatted(name, age, sex);
System.out.println(s); // 姓名 旺财,年龄 18,性别 男

/*
    占位符:
            %s字符串  %d整数  %f浮点数  %c字符  %b布尔值  %t时间
            %e科学计数法  %x十六进制  %o八进制  %h哈希码  %n换行
 */

在Java21中引入字符串模板,在字符串模板中允许在字符串中插入变量或表达式,而无需使用运算符 “+” 拼接字符串,这样可以使字符串拼接操作更加直观和方便。

STR模板处理器:STR是Java平台中的一种模板处理器,用于执行字符串的插值处理。通过STR可以将模板中的占位符或表达式动态替换为对应的值,生成最终的字符串输出。

STR是一个公共静态final字段,会自动导入到每个Java源文件中。

示例:字符串模板快速入门

String s1 = "hello";
String s2 = "world";
String target = STR."\{s1} \{s2}!"; //在字符串模板中使用`\{}`来引用变量
System.out.println(target); // hello world!
target = STR."\{s2}\{s1}";
System.out.println(target);// worldhello

示例:打印99乘法表

package cn.z3inc.jdk21;

import static java.lang.StringTemplate.STR;

public class StringTemplateTest {
    public static void main(String[] args) {
       for (int i = 1; i < 10; i++) {
          for (int j = 1; j < 10; j++) {
                if (j > i) {
                    break;
                }
                System.out.print(STR."\{j} * \{i} = \{i * j} \t");
          }
           System.out.println();
       }
    }
}

image-20230929210618078

示例:字符串中嵌入表达式(模板嵌套多了就不太直观了,可以分开写,拒绝套娃😉)

package cn.z3inc.jdk21;

import static java.lang.StringTemplate.STR;

public class StringTemplateTest {
    public static void main(String[] args) {
        String name = "白豆五";
        String str = STR. "\{
                isNotBlank(name) ? STR. "\{ name }签到成功" : "签到失败"
                } " ;
        System.out.println(str); //白豆五签到成功 
    }

    /**
     * 字符串非空判断
     *
     * @return 空串返回fale,否则返回true
     */
    public static boolean isNotBlank(String str) {
        return !(str == null || str.length() == 0);
    }
}

示例:多行模板表达式(类似python中的多行字符串输出)

package cn.z3inc.jdk21;

import static java.lang.StringTemplate.STR;

public class StringTemplateTest {
    public static void main(String[] args) {
        String title = "假装404";
        String text = "Hello, world";
        // 3个双引号代表多行字符串
        String html = STR. """
        <html>
          <head>
            <title>\{ title }</title>
          </head>
          <body>
            <p>\{ text }</p>
          </body>
        </html>
        """ ;
        System.out.println(html);
    }
}

image-20230929213801890


3.3 顺序集合

Sequenced Collections

在Java21中引入了全新的SequencedCollection、SequencedSet 、SequencedMap 接口,来表示顺序集合,这些接口提供了在集合开头或结尾处添加、修改或删除元素的方法,以及反转集合的功能。

image-20230929235818750

image-20230929235731060

image-20230929235949547

Java21集合体系结构:

image-20230930002211812

示例:

package cn.z3inc.jdk21;
import java.util.ArrayList;
import java.util.SequencedCollection;

public class SequencedCollectionsTest {
    public static void main(String[] args) {
        SequencedCollection<String> list = new ArrayList<>();
        list.add("b");
        list.addLast("c");
        list.addFirst("a");

        // 倒序遍历
        for (String s : list.reversed()) {
            System.out.println(s);
        }
    }
}

image-20230930004113685


3.4 记录模式(Record Patterns)

类似JS中的对象参数结构赋值,把Java中的Record对象拆解成多个变量。

示例:Record 快速入门

package cn.z3inc.jdk21;

//  老师类 record类型
public record Teacher(String name, int age) {  
}

/*
//record类的源码:
public final class Teacher extends java.lang.Record {
	// 字段初始化后不可变
    private final String name;
    private final int age;

	// 带参构造器
    public Teacher(String name, int age) {
        this.name = name;
        this.age = age;
    }

	//提供两个get方法
    public String name() {
        return name;
    }

    public int age() {
        return age;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == this) return true;
        if (obj == null || obj.getClass() != this.getClass()) return false;
        var that = (Teacher) obj;
        return Objects.equals(this.name, that.name) &&
                this.age == that.age;
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    @Override
    public String toString() {
        return "Teacher[" +
                "name=" + name + ", " +
                "age=" + age + ']';
    }
}

 */
package cn.z3inc.jdk21;

/**
 * 测试 记录模式
 * @author 白豆五
 * @date 2023/9/30
 * @since JDK21
 */
public class RecordTest {
    public static void main(String[] args) {
        Teacher teacher = new Teacher("张三", 18);
        System.out.println(teacher);
        System.out.println("name:"+teacher.name());
        System.out.println("age:"+teacher.age());
        System.out.println("equals:"+teacher.equals(new Teacher("张三", 18)));
        System.out.println("hashCode:"+teacher.hashCode());
        System.out.println("toString:"+teacher.toString());
    }
}

image-20230930012706946

示例2:

package cn.z3inc.jdk21;

// 老师类 记录类型
public record Teacher(String name, int age) {  
}
package cn.z3inc.jdk21;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 需求: 把老师数据转成java对象,保留20岁以上的老师,姓相同的分到一组
 *
 * @author 白豆五
 * @date 2023/9/30
 * @since JDK21
 */
public class RecordTest2 {
    public static void main(String[] args) {
        // 1. 模拟excel表格数据
        String cvs = """
                张三,23
                李四,20
                王五,19
                赵六,18
                张富贵,22
                李狗蛋,15                                         
                """;

        // 2. 按行切割字符串
        String[] splitArr = cvs.split("\n");

        // 3. 通过stream流处理数据
        Map<Character, List<Teacher>> map = Arrays.stream(splitArr)
                // 3.1. 把每一行数据转成Teacher对象
                .map(line -> {
                    String[] split = line.split(",");
                    return new Teacher(split[0], Integer.parseInt(split[1]));
                })
                // 3.2. 过滤掉年龄小于20岁的老师
                .filter(teacher -> teacher.age() >= 20)
                // 3.3. 按姓氏分组
                .collect(Collectors.groupingBy(teacher -> teacher.name().charAt(0)));

        System.out.println(map);
    }
}

image-20230930015837853

示例3:

package cn.z3inc.jdk21;

/**
 * 测试 记录模式
 * @author 白豆五
 * @date 2023/9/30
 * @since JDK21
 */
public class RecordTest3 {
    public static void main(String[] args) {
        print2(new Teacher("张三", 23));
    }

    /**
     * 传统方式写法
     *
     * @param o
     */
    @Deprecated
    static void print(Object o) {
        if (o instanceof Teacher) {
            Teacher t = (Teacher) o;
            System.out.println("name:" + t.name() + " ,age:" + t.age());
        }
    }

    /**
     * 记录模式写法
     * @param o
     */
    static void print2(Object o) {
        if (o instanceof Teacher(String name, int age)) { //解构记录对象中的值
            System.out.println("name:" + name + " ,age:" + age);
        }
    }
}

image-20230930021423829


3.5 未命名类和实例的main方法(预览版)

可以写类名,也可以不写类名。

image-20230930022047663

编译:

javac --release 21 --enable-preview MainTest.java

image-20230930022552725

运行:

java --enable-preview MainTest

image-20230930022958540


3.6 虚拟线程


todo

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1052311.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux】完美解决ubuntu18.04下vi不能使用方向键和退格键

今天在刚安装完ubuntu18.04&#xff0c;发现在使用vi命令配置文件时使用方向键并不能移动光标&#xff0c;而是出现一堆奇怪的英文字母&#xff0c;使用退格键也不能正常地删除内容&#xff0c;用惯了CentOS的我已经感觉到ubuntu没有centos用着丝滑&#xff0c;但是没办法&…

C++ -- 学习系列 std::deque 的原理与使用

一 deque 是什么? std::deque 是 c 一种序列式容器&#xff0c;其与 vector 类似&#xff0c;其底层内存都是连续的&#xff0c;不同的地方在于&#xff0c; vector 是一端开口&#xff0c;在一端放入数据与扩充空间&#xff0c;而 deque 是双端均开口&#xff0c;都可以放…

lv5 嵌入式开发-10 信号机制(下)

目录 1 信号集、信号的阻塞 2 信号集操作函数 2.1 自定义信号集 2.2 清空信号集 2.3 全部置1 2.4 将一个信号添加到集合中 2.5 将一个信号从集合中移除 2.6 判断一个信号是否在集合中 2.7 设定对信号集内的信号的处理方式(阻塞或不阻塞) 2.8 使进程挂起&#xff08;…

NLP 01(介绍)

一、NLP 自然语言处理 (Natural Language rrocessing,简称NLP) 是计算机科学与语言学中关注于计算机与人类语言间转换的领域。 1.1 发展 规则&#xff1a;基于语法 自然语言处理的应用场景: 语音助手 机器翻译 搜索引擎 智能问答

Windows下安装MySQL8详细教程

Windows下安装MySQL8详细教程 因为需要在Windows下安装MySQL8的数据库&#xff0c;做一个临时数据库环境。 1.准备软件 使用社区版本&#xff0c;下载地址如下&#xff1a; https://dev.mysql.com/downloads/mysql/ 使用8.0.16版本&#xff0c;需要在归档中查找 选择版本&a…

pysimpleGui 使用之sg.SaveAs使用

SaveAs与FileBrowse使用一样需要给指定target参数&#xff0c;保存路径 layout [ [ sg.FileBrowse( button_text“请选择单个文件”, # 按钮文本 target“single_path”, # 把选择后的路径保存到key为input_path的对象 # file_types((“All Files”, “.”),), # 默认筛选全部…

Python+Yolov8路面桥梁墙体裂缝识别

程序示例精选 PythonYolov8路面桥梁墙体裂缝识别 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对《PythonYolov8路面桥梁墙体裂缝识别》编写代码&#xff0c;代码整洁&#xff0c;规则&#…

如何应用MBTI职业性格测试来做职业规划

想要有一个不错的职业发展&#xff0c;需要做好职业规划。通常来说&#xff0c;职业规划可以分为三个组成&#xff0c;即定位、目标和路径。应用MBTI职业性格测试&#xff0c;可以对上述三个组成有更清晰的认识&#xff0c;帮助人们完成适合自己的职业规划。 职业性格和职业定…

Pytorch之ResNet图像分类

&#x1f482; 个人主页:风间琉璃&#x1f91f; 版权: 本文由【风间琉璃】原创、在CSDN首发、需要转载请联系博主&#x1f4ac; 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦 目录 前言 一、ResNet网络结构 1.residual结构 2.BN(Batch Normalization)层…

反射知识点学习

文章目录 1. Java 反射机制原理示意图1.1 反射相关的主要类1.2 反射的优点和缺点1.3 反射调用优化-关闭访问检查 2. Class 类2.1 基本介绍2.2 Class类的常用方法2.3 获取 Class 类对象 3. 哪些类型有 Class 对象4. 类加载4.1 基本说明4.2 类加载时机4.3 类加载过程图4.4 类加载…

国庆作业1

使用消息队列实现进程之间的通信 代码 write.c #include <myhead.h> //消息结构体 typedef struct {long msgtype; //消息类型char data[1024]; //消息正文 }Msg_ds;#define SIZE sizeof(Msg_ds)-sizeof(long) //正文大小 int main(int argc, cons…

算法-位运算-只出现一次的数字 II

算法-位运算-只出现一次的数字 II 1 题目概述 1.1 题目出处 https://leetcode.cn/problems/bitwise-and-of-numbers-range/description/?envTypestudy-plan-v2&envIdtop-interview-150 1.2 题目描述 2 逐个按位与运算 2.1 思路 最简单的就是直接挨个做与运算&#x…

transformers简介

目录 1、前言 2、网络结构 &#xff08;1&#xff09;、Transformers的总体架构可以分为四部分 &#xff08;2&#xff09;、输入文本包含 &#xff08;3&#xff09;、输出部分包含 &#xff08;4&#xff09;、编码器部分 &#xff08;5&#xff09;、解码器部分 1、前…

dbeaver连接国产数据库

dbeaver是常用的数据库连接工具。但是在连接一些国产的数据库时&#xff0c;因为没有可选的驱动&#xff0c;所以需要我们先设置驱动&#xff0c;在连接。以下是一个连接highgo例子。 首先先新增一个驱动&#xff1a; 在页面的菜单栏&#xff0c;选择 数据库 ->驱动管理器…

SpringBoot整合阿里云OSS文件存储解决方案

&#x1f9d1;‍&#x1f4bb;作者名称&#xff1a;DaenCode &#x1f3a4;作者简介&#xff1a;啥技术都喜欢捣鼓捣鼓&#xff0c;喜欢分享技术、经验、生活。 &#x1f60e;人生感悟&#xff1a;尝尽人生百味&#xff0c;方知世间冷暖。 &#x1f4d6;所属专栏&#xff1a;Sp…

【AI视野·今日Sound 声学论文速览 第十五期】Fri, 29 Sep 2023

AI视野今日CS.Sound 声学论文速览 Fri, 29 Sep 2023 Totally 1 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Sound Papers Audio-Visual Speaker Verification via Joint Cross-Attention Authors R. Gnana Praveen, Jahangir Alam使用语音信号进行了说话人验证的…

Web开发-新建Spring Boot项目

目录 Spring Boot 与 Web开发Spring Boot 与 MavenJava 环境搭建下载JDK下载xmapp下载navicat for mysql下载Eclipse配置tomcat配置maven 新建Spring Boot项目 Spring Boot 与 Web开发 Spring Boot 是一种用于简化 Spring 应用程序开发、部署和运行的框架&#xff0c;而 Web 开…

【LeetCode】滑动窗口妙解无重复字符的最长子串

Problem: 3. 无重复字符的最长子串 文章目录 思路算法原理分析暴力枚举 哈希表滑动窗口 复杂度Code 思路 首先我们来分析一下本题的思路 如果读者有看过 长度最小的子数组 的话就可以清楚这个子串其实和子数组是一个道理&#xff0c;都是 连续的一段区间但是呢它们本质上还是存…

【数据结构】队列和栈

大家中秋节快乐&#xff0c;玩了好几天没有学习&#xff0c;今天分享的是栈以及队列的相关知识&#xff0c;以及栈和队列相关的面试题 1.栈 1.1栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作…

Java字符缓冲流自己特有的方法进行读入和写出

代码如下&#xff1a; public class MyWork {public static void main(String[] args) throws IOException{BufferedReader fr new BufferedReader(new FileReader("myfile/abc.txt"));BufferedWriter fw new BufferedWriter(new FileWriter("myfile/test.tx…