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图像识别模型——数据预处理
上一篇:3 tensorflow构建模型详解-CSDN博客 本篇开始介绍识别猫狗图片的模型,内容较多,会分为多个章节介绍。模型构建还是和之前一样的流程: 数据集准备数据预处理创建模型设置损失函数和优化器训练模型 本篇先介绍数据集准备&am…...
SpringBoot整合RabbitMQ学习笔记
SpringBoot整合RabbitMQ学习笔记 以下三种类型的消息,生产者和消费者需各自启动一个服务,模拟生产者服务发送消息,消费者服务监听消息,分布式开发。 一 Fanout类型信息 . RabbitMQ创建交换机和队列 在RabbitMQ控制台,新…...
在校园跑腿系统小程序中,如何设计高效的实时通知与消息推送系统?
1. 选择合适的消息推送服务 在校园跑腿系统小程序中,选择一个适合的消息推送服务。例如,使用WebSocket技术、Firebase Cloud Messaging (FCM)、或第三方推送服务如Pusher或OneSignal等。注册并获取相关的API密钥或访问令牌。 2. 集成服务到小程序后端…...
求极限Lim x->0 (x-sinx)*e-²x / (1-x)⅓
题目如下: 解题思路: 这题运用了无穷小替换、洛必达法则、求导法则 具体解题思路如下: 1、首先带入x趋近于0,可以得到(0*1)/0,所以可以把e的-x的平方沈略掉 然后根据无穷小替换,利用t趋近于0时…...
JavaScript数据类型详细解析与代码实例
JavaScript是一种弱类型动态语言,数据类型分为原始类型和对象类型。 原始类型 原始类型包括:数字、字符串、布尔值和undefined、null。 数字 JavaScript中的数字类型包括整数和浮点数,可以进行基本的数学运算。 var num1 10; // 整数 v…...
.NET Framework中自带的泛型委托Func
Func<>是.NET Framework中自带的泛型委托,可以接收一个或多个输入参数,并且有返回值,和Action类似,.NET基类库也提供了多达16个输入参数的Func委托,输出参数只有1个。 1、Func泛型委托 .NET Framework为我们提…...
深入理解JVM虚拟机第十七篇:虚拟机栈中栈帧的内部结构
大神链接:作者有幸结识技术大神孙哥为好友,获益匪浅。现在把孙哥视频分享给大家。 孙哥链接:孙哥个人主页 作者简介:一个颜值99分,只比孙哥差一点的程序员 本专栏简介:话不多说,让我们一起干翻JavaScript 本文章简介:话不多说,让我们讲清楚虚拟机栈存储结构和运行原理…...
uniapp中地图定位功能实现的几种方案
1.uniapp自带uni.getLocation uni.getLocation(options) getlocation | uni-app官网 实现思路:uni.getLocation获取经纬度后调用接口获取城市名 优点:方便快捷,直接调用 缺点:关闭定位后延时很久,无法控制定位延迟…...
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是一个用于处理前端路由的中间件,它的原理是在服务器接收到请求时,检查请求的路径是否匹配到静态文件(如HTML、CSS、JS等),如果不匹配,则将请求重定向到前端的入口文件&#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 部署应用 概述 单机模式下,可以使用 Docker Compose 来编排多个服务。Docker Swarm 只能实现对单个服务的简单部署。而Docker Stack 只需对已有的 docker-compose.yml 配置文件稍加改造就可以完成 Docker 集群环境下的多服务编排。 stack是一组共享…...
Compose-Multiplatform在Android和iOS上的实践
本文字数:4680字 预计阅读时间:30分钟 01 简介 之前我们探讨过KMM,即Kotlin Multiplatform Mobile,是Kotlin发布的移动端跨平台框架。当时的结论是KMM提倡将共有的逻辑部分抽出,由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中,指令(Directives)是一种特殊的语法,用于为HTML元素添加特定的行为和功能。指令以v-作为前缀,通过在HTML标签中使用这些指令来操作DOM,修改元素的属性、样式或行为。 Vue.js提供了一组…...
优雅的 Dockerfile 是怎样炼成的?
Docker 简介 目前,Docker 主要有两个形态:Docker Desktop 和 Docker Engine。 Docker Desktop 是专门针对个人使用而设计的,支持 Mac(已支持arm架构的M系芯片) 和 Windows 快速安装,具有直观的图形界面&a…...
2023-2024 中国科学引文数据库来源期刊列表(CSCD)
文章目录 CSCD来源期刊遴选报告2023-2024 中国科学引文数据库来源期刊列表(CSCD) CSCD来源期刊遴选报告 2023-2024 中国科学引文数据库来源期刊列表(CSCD)...
【3D图像分割】基于Pytorch的VNet 3D图像分割5(改写数据流篇)
在这篇文章:【3D 图像分割】基于 Pytorch 的 VNet 3D 图像分割2(基础数据流篇) 的最后,我们提到了: 在采用vent模型进行3d数据的分割训练任务中,输入大小是16*96*96,这个的裁剪是放到Dataset类…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...
【Linux系统】Linux环境变量:系统配置的隐形指挥官
。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量:setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...
Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成
一个面向 Java 开发者的 Sring-Ai 示例工程项目,该项目是一个 Spring AI 快速入门的样例工程项目,旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计,每个模块都专注于特定的功能领域,便于学习和…...
