JDK 21新特性深度分析,但我用Java 8

news2024/12/28 3:59:28

官方文档链接:https://openjdk.org/projects/jdk/21/

下载链接:https://www.oracle.com/cn/java/technologies/downloads/#jdk21-windows

1、介绍

JDK21 是2023.09.19发布的正式版

image-20231031154835813

其他版本的含义:

  • Alpha:软件或系统的内部测试版本,仅内部人员使用。一般不向外部发布,通常会有很多 Bug,除非你也是测试人员,否则不建议使用,alpha 就是 α,是希腊字母的第一位,表示最初级的版本,beta 就是 β,alpha 版就是比 beta 还早的测试版,一般都是内部测试的版本。
  • Beta:公开测试版。β 是希腊字母的第二个,顾名思义,这一版本通常是在 Alpha 版本后,该版本相对于 Alpha 版已有了很大的改进,消除了严重的错误,但还是存在着一缺陷,需要经过多次测试来进一步消除。这个阶段的版本会一直加入新的功能。
  • Gamma: 软件或系统接近于成熟的版本,只需要做一些小的改进就能发行。是 beta 版做过一些修改,成为正式发布的候选版本。
  • RC:Release Candidate,发行候选版本。和 Beta 版最大的差别在于 Beta 阶段会一直加入新的功能,但是到了 RC 版本,几乎就不会加入新的功能了,而主要着重于除错。RC 版本是最终发放给用户的最接近正式版的版本,发行后改正 bug 就是正式版了,就是正式版之前的最后一个测试版。
  • GA:General Available,正式发布的版本,这个版本就是正式的版本。在国外都是用 GA 来说明 release 版本的。比如:MySQL Community Server 5.7.21 GA 这是 MySQL Community Server 5.7 第 21 个发行稳定的版本,GA 意味着 General Available,也就是官方开始推荐广泛使用了。
  • Release:这个版本通常就是所谓的“最终版本”,在前面版本的一系列测试版之后,终归会有一个正式版本,是最终交付用户使用的一个版本,该版本有时也称为标准版。一般情况下,Release 不会以单词形式出现在软件封面上,取而代之的是符号®。
  • Stable:稳定版。在开源软件中,都有 stable 版,这个就是开源软件的最终发行版,用户可以放心大胆的用了。这一版本基于 Beta 版,已知 Bug 都被修复,一般情况下,更新比较慢。

2、新功能

根据官方文档:https://www.infoq.com/news/2023/09/java-21-so-far/

最终的 15 个新功能集(以JEP的形式)可分为四 (4) 类:核心 Java 库Java 语言规范热点安全库,根据官方文档,分为了正式版和预览版,思维导图如下:

image-20231031155019384

正式功能

  1. 虚拟线程
  2. 序列集合
  3. 弃用 Windows 32 位 x86 移植
  4. 准备禁止动态加载代理
  5. 分代 ZGC
  6. switch 模式匹配
  7. 记录模式
  8. 密钥封装机制 API

预览版功能:

  1. 字符串模板(预览)
  2. 外部函数和内存 API(第三次预览)
  3. 未命名模式和变量(预览)
  4. 未命名类和实例主方法(预览)

3、虚拟线程

你发任你发,我用JAVA8

image-20231031155501090

提供了一种更高效、更轻量级的线程模型

1、为什么需要加入虚拟线程

在此之前,我们创建线程后需要销毁线程来释放内存,会造成大量的成本消耗,完美的解决方案就是我们用线程池,通过线程池来管理线程,并且共享线程相当于说我用的时候去租用一个线程。

这样就解决了创建和销毁的成本,但是呢,还有并发量没有解决,线程逐渐增多之后,线程之间会存在频繁切换,切换的成本很高

image-20231031155812419

so 就引入了虚拟线程,使用虚拟线程进行切换,这样成本就相当于只有一个线程在工作

2、使用

代码层面兼容性很好,基本和原来的线程池没有区别

首先创建一个普通线程,实现Runnable接口

public class ThreadDemo implements Runnable{
    @Override
    public void run() {
        System.out.println("线程名为:" + Thread.currentThread().getName());
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

1、通过Thread直接使用

Thread thread = Thread.startVirtualThread(new ThreadDemo());

2、使用ofVirtual(),构建器模式启动虚拟线程,您可以设置线程名称、优先级、异常处理和其他配置

Thread thread = Thread.ofVirtual().name("javaxiaobear").unstarted(new ThreadDemo());

3、通过Executors调用

try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    IntStream.range(0, 10_000).forEach(i -> {
        executor.submit(() -> {
            Thread.sleep(Duration.ofSeconds(1));
            return i;
        });
    });
}  // executor.close() is called implicitly, and waits

//另一种写法
ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor();
Future<?> submit = executorService.submit(new ThreadDemo());
Object javaxiaobear = submit.get();

4、使用工厂模式创建虚拟线程,其实跟ofVirtual差不多

ThreadFactory factory = Thread.ofVirtual().factory();
Thread thread = factory.newThread(new ThreadDemo());
thread.setName("javaxiaobear");
thread.start();
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    IntStream.range(0, 10_000).forEach(i -> {
        executor.submit(() -> {
            Thread.sleep(Duration.ofSeconds(1));
            return i;
        });
    });
}  // executor.close() is called implicitly, and waits

4、序列集合

官方文档:https://openjdk.org/jeps/431

Java 的集合框架缺少表示具有定义的遇到顺序的元素序列的集合类型,比如LinkedHashSet获取最后一个元素,就需要遍历整个集合,所以官方就增加了3个接口

有序集合是其Collection元素具有定义的遇到顺序的集合,有序集合具有第一个和最后一个元素,它们之间的元素具有后继和前驱。排序集合支持两端的通用操作,并且支持从第一个到最后一个以及从最后一个到第一个(即正向和反向)处理元素。

1、有序集合

interface SequencedCollection<E> extends Collection<E> {
    // new method
    SequencedCollection<E> reversed();
    // methods promoted from Deque
    void addFirst(E);
    void addLast(E);
    E getFirst();
    E getLast();
    E removeFirst();
    E removeLast();
}

2、序列集

interface SequencedSet<E> extends Set<E>, SequencedCollection<E> {
    SequencedSet<E> reversed();    // covariant override
}

3、序列Map

interface SequencedMap<K,V> extends Map<K,V> {
    // new methods
    SequencedMap<K,V> reversed();
    SequencedSet<K> sequencedKeySet();
    SequencedCollection<V> sequencedValues();
    SequencedSet<Entry<K,V>> sequencedEntrySet();
    V putFirst(K, V);
    V putLast(K, V);
    // methods promoted from NavigableMap
    Entry<K, V> firstEntry();
    Entry<K, V> lastEntry();
    Entry<K, V> pollFirstEntry();
    Entry<K, V> pollLastEntry();
}

image-20231031161135791

5、弃用 Windows 32 位 x86 移植

这里就很简单,未来将不支持32位的系统了

6、准备禁止动态加载代理

当代理动态加载到正在运行的 JVM 中时发出警告。这些警告旨在帮助用户为将来的版本做好准备,该版本默认情况下不允许动态加载代理,以提高默认情况下的完整性。在启动时加载代理的可服务性工具不会导致在任何版本中发出警告.

总的来说就是在JVM中禁止动态加载代理

在 JDK 21 中,允许动态加载代理,但 JVM 在发生这种情况时会发出警告。例如:

WARNING: A {Java,JVM TI} agent has been loaded dynamically (file:/u/bob/agent.jar)
WARNING: If a serviceability tool is in use, please run with -XX:+EnableDynamicAgentLoading to hide this warning
WARNING: If a serviceability tool is not in use, please run with -Djdk.instrument.traceUsage for more information
WARNING: Dynamic loading of agents will be disallowed by default in a future release

要允许工具动态加载代理而不发出警告,用户必须-XX:+EnableDynamicAgentLoading在命令行上使用该选项运行。

7、分代 ZGC

ZGC(JEP 333)专为低延迟和高可扩展性而设计,通过扩展 Z 垃圾收集器 ( ZGC ) 来维护年轻对象和老对象的不同代,从而提高应用程序性能。这将使 ZGC 能够更频繁地收集年轻对象(这些对象往往会在年轻时死亡)

在 Java 21 中,我们可以这样开启分代 ZGC:

java -XX:+UseZGC -XX:+ZGenerational ...

同时,分代 ZGC 中不再需要设置年轻代大小、年轻代进入老年代所需要的 GC 次数、GC 线程数等,ZGC 将这些全部动态化,并在内部自动调优。现在只需要设置一个参数,即最大内存大小 -Xmx

具体详情大家可参考这篇:https://sdl.moe/post/generational-zgc/

8、switch 模式匹配

官方文档:https://openjdk.org/jeps/441

switch 通过表达式和语句的模式匹配增强 Java 编程语言。扩展模式匹配switch允许针对多个模式测试表达式,每个模式都有一个特定的操作,以便可以简洁、安全地表达复杂的面向数据的查询,实际上就是一个语法升级,代码美观了

1、使用

public class SwitchTest {

    public static void main(String[] args) {
        int i = 88;
        System.out.println("以前写法"+ formatter(i));
        System.out.println(formatterPatternSwitch(i));
    }

    /**
     *  以前写法
     * @param obj
     * @return
     */
    public static String formatter(Object obj) {
        String formatted = "unknown";
        if (obj instanceof Integer i) {
            formatted = String.format("int %d", i);
        } else if (obj instanceof Long l) {
            formatted = String.format("long %d", l);
        } else if (obj instanceof Double d) {
            formatted = String.format("double %f", d);
        } else if (obj instanceof String s) {
            formatted = String.format("String %s", s);
        }
        return formatted;
    }

    /**
     * 现在写法
     * @param obj
     * @return
     */
    public static String formatterPatternSwitch(Object obj) {
        return switch (obj) {
            case Integer i -> String.format("int %d", i);
            case Long l    -> String.format("long %d", l);
            case Double d  -> String.format("double %f", d);
            case String s  -> String.format("String %s", s);
            default        -> obj.toString();
        };
    }
}

image-20231031161913779

2、空值处理

/**
 * 之前写法
 * @param s
 */
public static void testFooBarOld(String s) {
    if (s == null) {
        System.out.println("是空值!");
        return;
    }
    switch (s) {
        case "Foo", "Bar" -> System.out.println("Great");
        default           -> System.out.println("javaxiaobear is Good");
    }
}

/**
 * 新特性写法
 * @param s
 */
static void testFooBarNew(String s) {
    switch (s) {
        case null         -> System.out.println("Oops");
        case "Foo", "Bar" -> System.out.println("Great");
        default           -> System.out.println("javaxiaobear is Good");
    }
}

9、记录模式

官方文档:https://openjdk.org/jeps/440

Record Patterns的实现原理主要涉及两个方面:

  • 记录类型
  • 记录类型是一种新的类声明形式,通过record关键字来定义。

模式匹配

模式匹配是指根据给定的模式来匹配某个对象,并执行相应的操作。在Record Patterns中,我们可以使用instance of关键字和模式变量

来进行模式匹配。具体地说,当我们使用Record Patterns进行模式匹配时,编译器会自动为记录类型生成一个模式匹配方法。这个方法

接受一个对象作为参数兰担据给定的模式进行匹配。如果匹配成功,则将字段值绑定到相应的模式变量中,从而可以在后续代码中用。

10、密钥封装机制 API

引入密钥封装机制 (KEM) 的 API,这是一种使用公钥加密来保护对称密钥的加密技术。密钥封装是一种现代加密技术,它使用非对称或公钥加密来保护对称密钥。这样做的传统技术是使用公钥加密随机生成的对称密钥,但这需要填充并且很难证明安全。相反,密钥封装机制 (KEM) 使用公钥的属性来派生相关的对称密钥,这不需要填充。

KEM 由三个功能组成:

  • 密钥对生成函数,返回包含公钥和私钥的密钥对。
  • 密钥封装函数,由发送方调用,采用接收方的公钥和加密选项;它返回一个秘密密钥K 和一个密钥封装消息(在 ISO 18033-2 中称为*密文)。*发送方将密钥封装消息发送给接收方。
  • 密钥解封装函数,由接收方调用,获取接收方的私钥和接收到的密钥封装消息;它返回密钥K
import javax.crypto.KEM;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;

public class KEMTest {
    public static void main(String[] args) throws NoSuchAlgorithmException {
        //RSA算法
        KeyPairGenerator instance = KeyPairGenerator.getInstance("RSA");
        //初始化秘钥大小
        instance.initialize(1024);
        //生成密钥对
        KeyPair kp = instance.generateKeyPair();
        //获取公钥
        System.out.println(kp.getPublic());
        //获取私钥
        System.out.println(kp.getPrivate());

    }
}

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

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

相关文章

[JavaWeb]——面试官:谈谈你对springboot配置文件的理解

&#x1f308;键盘敲烂&#xff0c;年薪30万&#x1f308; 目录 一、springboot中三种配置文件对比 二、语法格式 propertiles yml(推荐) XML 前言&#xff1a; 什么是配置文件❓ 配置文件是用于存储程序或系统配置信息的文本文件。它通常包含了一些参数和选项&#xff0…

LEECODE 1480一维数组的动态和

class Solution { public:vector<int> runningSum(vector<int>& nums) {vector<int> runningSum;int sum 0;int len nums.size();for(int i 0; i < len; i){sum sum nums[i];runningSum.push_back(sum);}return runningSum;} };

算法通关村第四关-黄金挑战基础计算器问题

大家好我是苏麟 , 今天带来栈的比较难的问题 . 计算器问题 基础计算器 LeetCode 224 描述 : 给你一个字符串表达式 s &#xff0c;请你实现一个基本计算器来计算并返回它的值。 s 由数字、、-、(、)、和 组成s 表示一个有效的表达式 不能用作一元运算(例如&#xff0c; …

玩转硬件之Micro:bit的玩法(四)——声控灯

智能家居的普及在近几年来呈现出了爆发式的增长。随着科技的不断进步和人们对便利生活的追求&#xff0c;越来越多的家庭开始采用智能家居系统&#xff0c;使生活更加智能化、便捷化。 智能家居的普及不仅改变了人们的生活方式&#xff0c;也为家庭带来了更多的便利和舒适。现…

Betaflight 4.5 + Aocoda-RC F405V2 + AT32F435 Mark4 试飞初步总结

Betaflight 4.5 Aocoda-RC F405V2 AT32F435 Mark4 试飞初步总结 1. 源由2. 试飞3. 问题3.1 图传功率设置异常3.2 图传信号不理想3.3 ELRS915 信号差3.4 RSSI dbm告警3.5 翻滚不太顺手3.6 摄像头色彩异常3.7 磁力计指示方向异常 4. 参考资料 1. 源由 开销了一整天的时间&…

去除短视频平台水印 | 一键下载神器

当咱们这些视频创作者在短视频平台找素材的时候&#xff0c;经常会碰到下载下来居然带着平台水印的烦恼&#xff0c;这可让咱们的创作受到了限制和困扰不过别着急&#xff01;咱这就推荐几款超方便的短视频一键去水印下载工具&#xff0c;帮你快速去掉水印&#xff0c;轻松搞定…

第五章 基于视图的SysML模型|系统建模语言SysML实用指南学习

仅供个人学习记录 定制的机制在15.7节 定制语言部分阐述 仅记录个别值得专门记下来的概念 SysML视图 画布 图内容diagram context 也被称作画布canvas 省略号 显示省略号表示并非所有可视分区元素均显示 离页连接器 两节点之间的路径标识反映了节点所表示的两个模型元…

如何巧妙公布成绩

宝子们&#xff0c;来来来&#xff01;听说你们对如何公布学生成绩很头疼&#xff1f;别担心&#xff0c;今天就让我来给大家支支招&#xff01; 1在家长群内发公告&#xff0c;孩子的成绩已出&#xff0c;想知道具体成绩可以私信哦&#xff5e;简单粗暴&#xff01;关心孩子的…

会stm32有机会进大公司吗?

今日话题&#xff0c;会stm32有机会进大公司吗&#xff1f;我本科期间参与了飞思卡尔和电赛等比赛&#xff0c;使用过多种单片机&#xff0c;但渐渐发现单片机只是其中的一小部分。不要过分迷恋所谓的单片机基础和技巧&#xff0c;更值得深入研究的是C语言。如果你对此感兴趣&a…

【C++入门 三】学习C++缺省参数 | 函数重载 | 引用

C入门 三 1.缺省参数1.1 缺省参数概念1.2 缺省参数分类 2. 函数重载2.1 函数重载概念2.2 C支持函数重载的原理--名字修饰(name Mangling) 3.引用3.1引用概念3.2引用特性3.3 常引用3.4 使用场景1. 做参数2. 做返回值 3.5 传值、传引用效率比较3.6引用和指针的区别 4.引用和指针的…

Qt PingFang字体在Debian/Ubuntu上安装

1 下载ttf格式的字体库 2 将上图中的ttf文件拷贝到/usr/share/fonts/truetype 3 执行 fc-cache -f -v 4 如果qt程序字体效果未显示&#xff0c;可能与qt的字体路径有关 我这边是这样修改的&#xff1a;

使用 C# 在Word中插入图表

Word中的图表功能将数据可视化地呈现在文档中。这为展示数据和进行数据分析提供了一种方便且易于使用的工具&#xff0c;使作者能够以直观的方式传达信息。要通过C#代码来实现在Word中绘制图表&#xff0c;可以借助 Spire.Doc for .NET 控件&#xff0c;具体操作参考下文。 目录…

Qt QSystemTrayIcon实现系统托盘

1.简介 QSystemTrayIcon是Qt中的一个类&#xff0c;用于创建和管理系统托盘图标。系统托盘图标是显示在操作系统任务栏或通知区域的小图标&#xff0c;它可以用来在后台运行的应用程序中提供快速访问功能。 2.常用方法 设置托盘的显示图标 setIcon(const QIcon &icon) …

Python 文件处理:完整指南,一文够了

Python 是一种流行的解释型动态类型编程语言&#xff0c;用于构建 Web 服务、桌面应用程序、自动化脚本和机器学习项目。程序员在使用基于 Python 的软件项目时&#xff0c;通常必须访问操作系统的文件系统。 例如&#xff0c;我们使用文本文件作为输入&#xff0c;编写文本文…

用了这款插件,零代码基础也能写代码你信吗?

写在前面 使用过chatGPT的同学&#xff0c;可能都会有过这样的经历&#xff1f;遇到代码不会的问题&#xff0c;本能的就去求助chatGPT&#xff0c;然后并根据chatGPT的回答去优化代码。但是&#xff0c;没了梯子的话&#xff0c;chatGPT是不是也帮不上忙了&#xff1f;还是只…

课程学习前言

App逆向说明 app抓包分析可以看到有签名有加固&#xff0c;毕竟需要APK去访问服务、获取数据&#xff0c;都需要APK有完整的信息&#xff0c;而这些信息、代码经过各种加密&#xff0c;还是放在APK里面。说白了&#xff0c;就是门锁紧了&#xff0c;钥匙藏在门口某个地方&…

英语语法,时态总结,16种时态

文章目录 前言总体说明过去时一般过去时过去进行时过去完成时过去完成进行时 现在时一般现在时现在进行时现在完成时现在完成进行时 将来时一般将来时将来进行时将来完成时将来完成进行时 过去将来时一般过去将来时过去将来进行时过去将来完成时过去将来完成进行时 前言 学了这…

零日漏洞预防

零日漏洞&#xff0c;是软件应用程序或操作系统&#xff08;OS&#xff09;中的意外安全漏洞&#xff0c;负责修复该漏洞的一方或供应商不知道该漏洞&#xff0c;它们仍然未被披露和修补&#xff0c;为攻击者留下了漏洞&#xff0c;而公众仍然没有意识到风险。 零日攻击是如何…

项目上线前发现严重Bug怎么办?

今天分享一个面试问题&#xff0c;现在有一个面试场景&#xff1a; 项目计划明天发布&#xff0c;但是在今天你作为测试人员发现了一个严重的bug&#xff0c;市场相关人员又在催发布的事情&#xff0c;这个时候你应该怎么办&#xff1f; 这是测试工程师不管是在面试&#xff0…

【计算机组成原理】CPU的工作原理

一.CPU的组成结构 CPU主要有运算器、控制器、寄存器和内部总线等组成&#xff0c;其大概的样子长这样&#xff1a; 看不懂没关系&#xff0c;我们将采用自顶而下的方法来讲解CPU的具体工作原理&#xff0c;我们首先来说一下什么叫寄存器&#xff0c;顾名思义&#xff0c;寄存器…