当前位置: 首页 > news >正文

Java21新特性

目录

一、Java21新特性

1、字符串模版

2、scoped values

3、record pattern

4、switch格式匹配

5、可以在switch中使用when

6、Unnamed Classes and Instance Main Methods

7、Structured Concurrency


一、Java21新特性

1、字符串模版

        字符串模版可以让开发者更简洁的进行字符串拼接(例如拼接sql,xml,json等)。该特性并不是为字符串拼接运算符+提供的语法,也并非为了替换StringBuffer和StringBuilder。

利用STR模版进行字符串与变量的拼接

public class StringTest {public static void main(String[] args) {String sport="basketball";String msg=STR."I like \{sport}";System.out.println(msg);}
}
预览功能(java文件不要加package包信息)
$>javac --enable-preview -source 21 StringTest.java
注: StringTest.java 使用 Java SE 21 的预览功能。
注: 有关详细信息,请使用 -Xlint:preview 重新编译。
$>java --enable-preview  StringTest
I like basketball

上面使用的STR是java中定义的模版处理器,它可以将变量的值取出,完成字符串的拼接。在每个java源文件中都引入了一个public static final修饰的STR属性,STR通过打印STR可以知道它是java.lang.StringTemplate,是一个接口。

Processor<String, RuntimeException> STR = StringTemplate::interpolate;default String interpolate() {return StringTemplate.interpolate(fragments(), values());}static String interpolate(List<String> fragments, List<?> values) {Objects.requireNonNull(fragments, "fragments must not be null");Objects.requireNonNull(values, "values must not be null");int fragmentsSize = fragments.size();int valuesSize = values.size();if (fragmentsSize != valuesSize + 1) {throw new IllegalArgumentException("fragments must have one more element than values");}JavaTemplateAccess JTA = SharedSecrets.getJavaTemplateAccess();return JTA.interpolate(fragments, values);}public static JavaTemplateAccess getJavaTemplateAccess() {var access = javaTemplateAccess;if (access == null) {try {Class.forName("java.lang.runtime.TemplateSupport", true, null);access = javaTemplateAccess;} catch (ClassNotFoundException e) {}}return access;}final class TemplateSupport implements JavaTemplateAccess {
...@Overridepublic String interpolate(List<String> fragments, List<?> values) {int fragmentsSize = fragments.size();int valuesSize = values.size();if (fragmentsSize == 1) {return fragments.get(0);}int size = fragmentsSize + valuesSize;String[] strings = new String[size];int i = 0, j = 0;for (; j < valuesSize; j++) {strings[i++] = fragments.get(j);strings[i++] = String.valueOf(values.get(j));}strings[i] = fragments.get(j);return JLA.join("", "", "", strings, size);}

其他使用示例,在STR中可以进行基本的运算(支持三元运算)

int x=10,y=20;
String result=STR."\{x} + \{y} = \{x+y}";
System.out.println(result);//10 + 20 = 30

调用方法

String res=STR."获取一个随机数:\{Math.random()}";
System.out.println(res);

获取属性

String res1=STR."int的最大值是:\{Integer.MAX_VALUE}";
System.out.println(res1);

查看时间

String res2=STR."现在时间:\{new SimpleDateFormat("yyyy-MM-dd").format(new Date()) }";
System.out.println(res2);

计数操作

int index=0;
String result=STR."\{index++},\{index++},\{index++}";
System.out.println(result);

获取数组数据

String[] cars ={"bmw","ben","audi"};
String result = STR. "\{ cars[0] },\{ cars[1] },\{ cars[2] }" ;
System.out.println(result);

拼接多行数据

String[] cars ={"bmw","ben","audi"};
String result = STR. """\{cars[0] }\{ cars[1] }\{ cars[2] }""" ;
System.out.println(result);

自定义模版

    public static void main(String[] args) {var INTER = StringTemplate.Processor.of((StringTemplate st) -> {StringBuilder sb = new StringBuilder();Iterator<String> iterator = st.fragments().iterator();for (Object value : st.values()) {sb.append(iterator.next());sb.append(value);}sb.append(iterator.next());return sb.toString();});int x = 10, y = 20;String result = INTER. "\{ x } + \{ y } = \{ x + y }" ;System.out.println(result);}

2、scoped values

scoped values是一个隐藏的方法参数,只有方法可以访问scoped values,它可以让两个方法之间传递参数时无需声明形参。例如在UserDao类中编写savaUser方法,LogDao类中编写了saveLog方法,那么在保存用户的时候需要保证事务,此时就需要在service层获取Connection对象,然后将该对象分别传入到两个Dao的方法中,但对于savaUser方法来说并不是直接使用Connection对象,却又不得不在方法的形参中写上该对象,其实仅从业务上来看,该方法中只要传入User对象就可以了。

public class ScopeedValueTest {private static final ScopedValue<String> GIFT=ScopedValue.newInstance();public static void main(String[] args) {ScopeedValueTest scopeedValueTest=new ScopeedValueTest();scopeedValueTest.giveGift();}public void giveGift(){ScopedValue.where(GIFT,"手机").run(()->recieveGift());}public void recieveGift(){System.out.println(GIFT.get());}
}

多线程环境是否会出问题

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ScopeedValueTest {private static final ScopedValue<String> GIFT = ScopedValue.newInstance();public static void main(String[] args) {ScopeedValueTest t = new ScopeedValueTest();ExecutorService pool = Executors.newCachedThreadPool();for (int i = 0; i < 10; i++) {pool.submit(() -> {t.giveGift();});}pool.shutdown();}public void giveGift() {ScopedValue.where(GIFT, Thread.currentThread().getName()).run(() -> recieveGift());}public void recieveGift() {System.out.println(GIFT.get());}
}

变更中间数值,和当前线程绑定关系

public class ScopeedValueTest {private static final ScopedValue<String> GIFT = ScopedValue.newInstance();public static void main(String[] args) {ScopeedValueTest t = new ScopeedValueTest();t.giveGift();}public void giveGift() {ScopedValue.where(GIFT, "500").run(() -> recieveMiddleMan());}//中间人public void recieveMiddleMan() {System.out.println(GIFT.get());//500ScopedValue.where(GIFT, "200").run(() -> recieveGift());//中间人抽成300System.out.println("recieveMiddleMan=" + GIFT.get());//500}public void recieveGift() {System.out.println(GIFT.get());//200}
}

3、record pattern

通过该特性可以解构record类型中的值,例如:

public class RecordTest {public static void main(String[] args) {Student s = new Student(1, "小米");print(s);}static void print(Object obj) {if (obj instanceof Student(int a, String b)) {System.out.println("a=" + a);System.out.println("b=" + b);}}
}record Student(int id, String name) {}

4、switch格式匹配

public class SwitchTest {public static void main(String[] args) {String str="hello";String result = getObjInstance(str);System.out.println(result);}public static String getObjInstance(Object obj) {return switch (obj) {case null -> "空对象";case Integer i -> "Integer对象" + i;case String s -> "String对象" + s;default -> obj.toString();};}
}

5、可以在switch中使用when

public class Switch02Test {public static void main(String[] args) {yesOrNo("yes");}public static void yesOrNo(String str) {switch (str) {case null -> {System.out.println("空对象");}case String swhen s.equalsIgnoreCase("yes") -> {System.out.println("确定");}case String swhen s.equalsIgnoreCase("no") -> {System.out.println("取消");}case String s -> {System.out.println("请输入yes或no");}}}
}

6、Unnamed Classes and Instance Main Methods

对于初学者来说,写第一个HelloWorld代码有太多的概念,为了方便初学者快速编写第一段java代码,这里提出了无名类和实例main方法,下面代码可以直接运行编译,相当于是少了类的定义,main方法的修饰符和形参也省略掉了。

void main() {System.out.println("Hello,World!");
}

7、Structured Concurrency

结构化并发:该特性主要作用是在使用虚拟线程时,可以使任务和子任务的代码编写起来可读性更强,维护性更高,更加可靠。

import java.util.concurrent.ExecutionException;
import java.util.concurrent.StructuredTaskScope;
import java.util.function.Supplier;public class Test {public static void main(String[] args) {Food f = new Test().handle();System.out.println(f);}Food handle() {try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {Supplier<String> fork1 = scope.fork(() -> "奶茶做好了");//任务1:线程1Supplier<String> fork2 = scope.fork(() -> "烤串烤好了");//任务2:线程2scope.join().throwIfFailed();//失败传播//当两个任务都成功后,最终才能吃饭return new Food(fork1.get(), fork2.get());} catch (ExecutionException e) {throw new RuntimeException(e);} catch (InterruptedException e) {throw new RuntimeException(e);}}
}record Food(String f1, String f2) {}

Java17-20新特性

一个程序员最重要的能力是:写出高质量的代码!!
有道无术,术尚可求也,有术无道,止于术。
无论你是年轻还是年长,所有程序员都需要记住:时刻努力学习新技术,否则就会被时代抛弃!

相关文章:

Java21新特性

目录 一、Java21新特性 1、字符串模版 2、scoped values 3、record pattern 4、switch格式匹配 5、可以在switch中使用when 6、Unnamed Classes and Instance Main Methods 7、Structured Concurrency 一、Java21新特性 1、字符串模版 字符串模版可以让开发者更简洁的…...

4 Tensorflow图像识别模型——数据预处理

上一篇&#xff1a;3 tensorflow构建模型详解-CSDN博客 本篇开始介绍识别猫狗图片的模型&#xff0c;内容较多&#xff0c;会分为多个章节介绍。模型构建还是和之前一样的流程&#xff1a; 数据集准备数据预处理创建模型设置损失函数和优化器训练模型 本篇先介绍数据集准备&am…...

SpringBoot整合RabbitMQ学习笔记

SpringBoot整合RabbitMQ学习笔记 以下三种类型的消息&#xff0c;生产者和消费者需各自启动一个服务&#xff0c;模拟生产者服务发送消息&#xff0c;消费者服务监听消息&#xff0c;分布式开发。 一 Fanout类型信息 . RabbitMQ创建交换机和队列 在RabbitMQ控制台&#xff0c;新…...

在校园跑腿系统小程序中,如何设计高效的实时通知与消息推送系统?

1. 选择合适的消息推送服务 在校园跑腿系统小程序中&#xff0c;选择一个适合的消息推送服务。例如&#xff0c;使用WebSocket技术、Firebase Cloud Messaging (FCM)、或第三方推送服务如Pusher或OneSignal等。注册并获取相关的API密钥或访问令牌。 2. 集成服务到小程序后端…...

求极限Lim x->0 (x-sinx)*e-²x / (1-x)⅓

题目如下&#xff1a; 解题思路: 这题运用了无穷小替换、洛必达法则、求导法则 具体解题思路如下: 1、首先带入x趋近于0&#xff0c;可以得到&#xff08;0*1&#xff09;/0&#xff0c;所以可以把e的-x的平方沈略掉 然后根据无穷小替换&#xff0c;利用t趋近于0时&#xf…...

JavaScript数据类型详细解析与代码实例

JavaScript是一种弱类型动态语言&#xff0c;数据类型分为原始类型和对象类型。 原始类型 原始类型包括&#xff1a;数字、字符串、布尔值和undefined、null。 数字 JavaScript中的数字类型包括整数和浮点数&#xff0c;可以进行基本的数学运算。 var num1 10; // 整数 v…...

.NET Framework中自带的泛型委托Func

Func<>是.NET Framework中自带的泛型委托&#xff0c;可以接收一个或多个输入参数&#xff0c;并且有返回值&#xff0c;和Action类似&#xff0c;.NET基类库也提供了多达16个输入参数的Func委托&#xff0c;输出参数只有1个。 1、Func泛型委托 .NET Framework为我们提…...

深入理解JVM虚拟机第十七篇:虚拟机栈中栈帧的内部结构

大神链接:作者有幸结识技术大神孙哥为好友,获益匪浅。现在把孙哥视频分享给大家。 孙哥链接:孙哥个人主页 作者简介:一个颜值99分,只比孙哥差一点的程序员 本专栏简介:话不多说,让我们一起干翻JavaScript 本文章简介:话不多说,让我们讲清楚虚拟机栈存储结构和运行原理…...

uniapp中地图定位功能实现的几种方案

1.uniapp自带uni.getLocation uni.getLocation(options) getlocation | uni-app官网 实现思路&#xff1a;uni.getLocation获取经纬度后调用接口获取城市名 优点&#xff1a;方便快捷&#xff0c;直接调用 缺点&#xff1a;关闭定位后延时很久&#xff0c;无法控制定位延迟…...

JS功能实现

目录 轮播图移动端轮播图按下回车发表评论tab栏切换全选按钮 轮播图 <style>* {box-sizing: border-box;}.slider {width: 560px;height: 400px;overflow: hidden;}.slider-wrapper {width: 100%;height: 320px;}.slider-wrapper img {width: 100%;height: 100%;display:…...

connect-history-api-fallback原理

connect-history-api-fallback是一个用于处理前端路由的中间件&#xff0c;它的原理是在服务器接收到请求时&#xff0c;检查请求的路径是否匹配到静态文件&#xff08;如HTML、CSS、JS等&#xff09;&#xff0c;如果不匹配&#xff0c;则将请求重定向到前端的入口文件&#x…...

Android ConstraintLayout分组堆叠圆角ShapeableImageView

Android ConstraintLayout分组堆叠圆角ShapeableImageView <?xml version"1.0" encoding"utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"…...

Docker Stack部署应用详解+Tomcat项目部署详细实战

Docker Stack 部署应用 概述 单机模式下&#xff0c;可以使用 Docker Compose 来编排多个服务。Docker Swarm 只能实现对单个服务的简单部署。而Docker Stack 只需对已有的 docker-compose.yml 配置文件稍加改造就可以完成 Docker 集群环境下的多服务编排。 stack是一组共享…...

Compose-Multiplatform在Android和iOS上的实践

本文字数&#xff1a;4680字 预计阅读时间&#xff1a;30分钟 01 简介 之前我们探讨过KMM&#xff0c;即Kotlin Multiplatform Mobile&#xff0c;是Kotlin发布的移动端跨平台框架。当时的结论是KMM提倡将共有的逻辑部分抽出&#xff0c;由KMM封装成Android(Kotlin/JVM)的aar和…...

XXL-JOB 默认 accessToken 身份绕过导致 RCE

文章目录 0x01 漏洞介绍0x02 影响版本0x03 环境搭建0x04 漏洞复现第一步 访问页面返回报错信息第二步 执行POC,进行反弹shell第三步 获取shell0x05 修复建议摘抄免责声明0x01 漏洞介绍 XXL-JOB 是一款开源的分布式任务调度平台,用于实现大规模任务的调度和执行。 XXL-JOB 默…...

7 库函数之复位和时钟设置(RCC)所有函数的介绍及使用

7 库函数之复位和时钟设置(RCC)所有函数的介绍及使用的介绍及使用 1. 图片有格式二、RCC库函数固件库函数预览2.1 函数RCC_DeInit2.2 函数RCC_HSEConfig2.3 函数RCC_WaitForHSEStartUp2.4 函数RCC_AdjustHSICalibrationValue2.5 函数RCC_HSICmd2.6 函数RCC_PLLConfig2.7 函数…...

第十七节——指令

一、概念 在Vue.js中&#xff0c;指令&#xff08;Directives&#xff09;是一种特殊的语法&#xff0c;用于为HTML元素添加特定的行为和功能。指令以v-作为前缀&#xff0c;通过在HTML标签中使用这些指令来操作DOM&#xff0c;修改元素的属性、样式或行为。 Vue.js提供了一组…...

优雅的 Dockerfile 是怎样炼成的?

Docker 简介 目前&#xff0c;Docker 主要有两个形态&#xff1a;Docker Desktop 和 Docker Engine。 Docker Desktop 是专门针对个人使用而设计的&#xff0c;支持 Mac&#xff08;已支持arm架构的M系芯片&#xff09; 和 Windows 快速安装&#xff0c;具有直观的图形界面&a…...

2023-2024 中国科学引文数据库来源期刊列表(CSCD)

文章目录 CSCD来源期刊遴选报告2023-2024 中国科学引文数据库来源期刊列表&#xff08;CSCD&#xff09; CSCD来源期刊遴选报告 2023-2024 中国科学引文数据库来源期刊列表&#xff08;CSCD&#xff09;...

【3D图像分割】基于Pytorch的VNet 3D图像分割5(改写数据流篇)

在这篇文章&#xff1a;【3D 图像分割】基于 Pytorch 的 VNet 3D 图像分割2&#xff08;基础数据流篇&#xff09; 的最后&#xff0c;我们提到了&#xff1a; 在采用vent模型进行3d数据的分割训练任务中&#xff0c;输入大小是16*96*96&#xff0c;这个的裁剪是放到Dataset类…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?

在工业自动化持续演进的今天&#xff0c;通信网络的角色正变得愈发关键。 2025年6月6日&#xff0c;为期三天的华南国际工业博览会在深圳国际会展中心&#xff08;宝安&#xff09;圆满落幕。作为国内工业通信领域的技术型企业&#xff0c;光路科技&#xff08;Fiberroad&…...

高考志愿填报管理系统---开发介绍

高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发&#xff0c;采用现代化的Web技术&#xff0c;为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## &#x1f4cb; 系统概述 ### &#x1f3af; 系统定…...

spring Security对RBAC及其ABAC的支持使用

RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型&#xff0c;它将权限分配给角色&#xff0c;再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...

解析“道作为序位生成器”的核心原理

解析“道作为序位生成器”的核心原理 以下完整展开道函数的零点调控机制&#xff0c;重点解析"道作为序位生成器"的核心原理与实现框架&#xff1a; 一、道函数的零点调控机制 1. 道作为序位生成器 道在认知坐标系$(x_{\text{物}}, y_{\text{意}}, z_{\text{文}}…...