从JDK 17 到 JDK 21:Java 新特性
JDK17
密封类
概念:密封类允许开发者控制哪些类可以继承或实现特定的类或接口。通过这种方式,密封类为类的继承提供了更高的安全性和可维护性。
定义:使用sealed代表该类为密封类,并用permits限制哪些类可以继承。
public sealed class Shape permits Circle, Square {// 类体
}public final class Circle extends Shape {// 类体
}public final class Square extends Shape {// 类体
}
继承类必须由final,sealed,non-sealed修饰。
- final代表该继承类不能被任何类继承
- sealed代表该类依然是继承类
- non-sealed代表该类不受任何限制
优势:
- 增强可维护性: 开发者可以清晰地定义哪些类可以扩展特定类,从而更好地控制代码的变化。
- 提高安全性: 限制类的继承可以防止不受控制的扩展,降低代码出错的概率。
- 更好的设计: 密封类可以使类的层次结构更加明确,符合设计模式的要求。
简化instanceof
在JDK16及以前需要先进行类型判断然后强制转换获取对象
public class Main {public static void main(String[] args) {Object obj = "Hello, World!"; // String 类型的对象if (obj instanceof String) {String str = (String) obj; // 强制转换System.out.println(str.toUpperCase()); // 使用转换后的字符串}}
}
在JDK17开始可以合二为一
public class Main {public static void main(String[] args) {Object obj = "Hello, World!"; // String 类型的对象if (obj instanceof String str) { // 类型检查和转换System.out.println(str.toUpperCase()); // 直接使用 str}}
}
优点:
- 简洁性: 通过将类型检查和转换合并为一个操作,代码更加简洁,减少了冗余。
- 可读性: 减少了强制转换的显式写法,使得代码更易于理解。
- 减少出错: 避免了在进行强制转换时可能出现的
ClassCastException
异常,因为编译器会确保类型检查的正确性。
增强Switch
基本示例
增强的 switch
表达式允许使用“箭头”语法 (->
),这使得每个 case
分支可以直接返回一个值或执行一段代码。以下是基本的语法示例:
int day = 3; // 假设 1 = 星期一,2 = 星期二,...String dayType = switch (day) {case 1, 7 -> "Weekend"; // 支持多个 case 用逗号分隔case 2, 3, 4, 5, 6 -> "Weekday"; // 其他工作日default -> throw new IllegalArgumentException("Invalid day: " + day); // 默认情况
};System.out.println(dayType); // 输出: Weekday
代码块支持
除了简单的返回值,switch
表达式还支持代码块,你可以在 case
中包含多行代码。这时需要使用 {}
来包裹代码块,并且要使用 yield
语句返回值。
public class Main {public static void main(String[] args) {int day = 5; // 假设 1 = 星期一,2 = 星期二,...String dayType = switch (day) {case 1, 7 -> "Weekend";case 2, 3, 4, 5, 6 -> "Weekday";default -> throw new IllegalArgumentException("Invalid day: " + day);};System.out.println("Day " + day + " is a " + dayType);}
}
文本块增强
基本概念
文本块允许以更直观的方式定义多行字符串,使用三重引号("""
)来包裹文本内容。这样,文本块中的换行、缩进和其他空白字符将被直接保留,增强了可读性。
基本用法
基本的文本块用法如下所示:
java复制代码String textBlock = """This is a text block.It can span multiple lines.""";
文本块的增强
在 Java 17 中,对文本块进行了增强,主要体现在以下几个方面:
换行和缩进处理
- 自动去除公共前缀: 文本块的自动缩进特性可以去除公共前缀。这意味着,如果文本块的所有行都有相同的前缀空白(缩进),在生成的字符串中,这些空白将会被自动去除。
示例:
java复制代码String textBlock = """Line 1Line 2Line 3""";System.out.println(textBlock);
输出将是:
Line 1
Line 2
Line 3
在这个示例中,公共前缀的空白会被自动去除。
使用表达式插入文本
文本块可以与表达式结合,允许在文本块中插入动态内容。这使得文本块更加灵活和动态。
示例:
java复制代码String name = "John";
String greeting = """Hello, %s!Welcome to the Java world.""".formatted(name);System.out.println(greeting);
输出将是:
Hello, John!
Welcome to the Java world.
在这个示例中,使用了 String.formatted()
方法来插入变量。
支持 Unicode 字符
文本块支持 Unicode 字符,使得在字符串中包含特殊字符变得更加方便。例如,你可以直接在文本块中使用中文字符、表情符号等。
示例:
String unicodeTextBlock = """Hello, 世界! 🌍This is a text block with Unicode characters.""";System.out.println(unicodeTextBlock);
输出将是:
Hello, 世界! 🌍
This is a text block with Unicode characters.
JDK21
虚拟线程
为什么引入?
线程的缺点有两个:
- 创建销毁成本高
- 频繁切换成本高
第一个缺点已经通过线程池解决了,第二个在JDK21通过虚拟线程也得到了解决。
概念与优势
虚拟线程被设计为轻量级的执行单元,可以在 JVM 中并发执行。虚拟线程使得开发者能够创建和管理数以千计的并发任务,而无需像使用传统线程那样消耗大量资源。
优势:
- 轻量级: 虚拟线程的内存开销和启动时间都大大低于操作系统线程。这使得创建和管理虚拟线程变得更加高效。
- 易于使用: 开发者可以使用简单的代码结构来编写并发任务,而无需管理线程的生命周期和状态。
- 高并发: 虚拟线程允许在单个 JVM 实例中并发运行数以千计的虚拟线程,非常适合 I/O 密集型和网络应用程序。
使用
虚拟线程在代码上兼容极好,跟传统线程区别不大。
直接创建虚拟线程
public class VirtualThreadExample {public static void main(String[] args) {Thread virtualThread = Thread.ofVirtual().start(() -> {System.out.println("This is a virtual thread!");});virtualThread.join();}
}
通过线程池获取
// 创建一个虚拟线程池ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();// 提交多个任务到虚拟线程池for (int i = 0; i < 10; i++) {final int taskId = i;executor.submit(() -> {});}// 关闭线程池executor.shutdown();
序列集合
在之前的版本中,List、Set、LinkedHashSet这些不同的集合获取首尾元素的方式不同,api不同,很折磨人。
序列集合是一类新接口,与常规集合(如 List
和 Set
)不同,序列集合强调保持元素的插入顺序,并提供了一种更灵活的元素处理方式。
interface sequencedcollection<E>extends colection<E>{Sequencedco1lection<E> reversed(),void addLast(E);E getFirst();E getLast();E removeFirst;E removeLast();
}
有个序列集合后就不用因为不统一的api发愁了。
Record
介绍
定义: Record
是一种特殊的类,用于表示不可变的数据模型。它自动为每个字段生成构造函数、访问器(getter)和其他一些方法(如 toString()
、equals()
和 hashCode()
)。
语法: 创建 Record
类的语法非常简洁,类似于定义普通类。记录类的定义如下:
public record Person(String name, int age) { }
特性
不可变性:
Record
实例是不可变的,一旦创建,字段的值就不能被修改。这确保了数据的一致性和安全性,尤其是在多线程环境中。
自动生成方法:
- 构造函数: 自动生成一个构造函数,接受所有字段作为参数。
- 访问器: 为每个字段生成一个访问器方法,名称与字段相同,但没有前缀。例如,上述
Person
记录将具有name()
和age()
方法。 toString()
: 自动生成一个toString()
方法,返回所有字段的名称和值。equals()
和hashCode()
: 自动实现equals()
和hashCode()
方法,以支持基于内容的比较和集合操作。
JDK21增强特性
record
中的泛型
Record
现在可以定义为泛型类。这使得你能够创建更具通用性和复用性的记录类:
public record Box<T>(T content) { }
sealed
Record
可以将 Record
声明为 sealed
,限制哪些类可以扩展该 Record
:
public sealed record Shape permits Circle, Square { }public record Circle(double radius) extends Shape { }public record Square(double side) extends Shape { }
记录的嵌套记录
你可以在 Record
中嵌套另一个 Record
,这使得组织复杂数据模型更为简洁:
public record Address(String street, String city) { }public record Person(String name, int age, Address address) { }
使用场景
数据传输对象(DTO)
场景描述: DTO 是一种简单的对象,用于封装数据并在不同层或模块之间传递。使用 Record
可以减少样板代码。
示例代码:
// 数据传输对象
public record UserDTO(String username, String email, int age) { }public class UserService {public UserDTO getUser(int id) {// 假设从数据库获取用户数据return new UserDTO("xxx", "xxx@qq.com", 25);}
}public class Main {public static void main(String[] args) {UserService userService = new UserService();UserDTO user = userService.getUser(1);System.out.println(user.username()); System.out.println(user.email()); System.out.println(user.age()); }
}
返回类型
场景描述: 方法需要返回多个值时,使用 Record
可以将这些值组合在一起,避免使用数组或其他复杂的数据结构。
配置和设置
场景描述: 在需要表示一组配置参数或设置选项时,Record
可以提供清晰和易于维护的表示方式。
示例代码:
// 配置类
public record DatabaseConfig(String url, String username, String password) { }
总结
通过记录我们可以把之前需要创建类或者构建复杂数据结构的场景简化,记录会自动创建一些方法供我们使用,所以只需要简单声明记录类即可。
相关文章:
从JDK 17 到 JDK 21:Java 新特性
JDK17 密封类 概念:密封类允许开发者控制哪些类可以继承或实现特定的类或接口。通过这种方式,密封类为类的继承提供了更高的安全性和可维护性。 定义:使用sealed代表该类为密封类,并用permits限制哪些类可以继承。 public sea…...
【计算机网络 - 基础问题】每日 3 题(五十七)
✍个人博客:https://blog.csdn.net/Newin2020?typeblog 📣专栏地址:http://t.csdnimg.cn/fYaBd 📚专栏简介:在这个专栏中,我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞…...
第十二章 章节练习created的应用
目录 一、引言 二、运行效果图 三、完整代码 一、引言 构建一个新闻的页面,页面在响应式数据准备好之后(即created),就向后台接口请求获取新闻数据列表,然后赋值给Vue实例中的list列表,这个请求逻辑我…...
Unity 游戏性能优化实践:内存管理与帧率提升技巧
1. 引言 随着移动设备性能的逐步提升,游戏玩家对画质和流畅度的要求越来越高。优化 Unity 游戏性能不仅可以提升用户体验,还能降低设备的功耗,延长电池寿命。这篇文章将深入探讨如何在 Unity 中优化游戏的内存管理与帧率,通过多方…...
C++游戏开发详解
C 是一种广泛使用的编程语言,尤其在游戏开发领域有着不可替代的地位。它提供了对底层硬件的直接访问能力,允许开发者优化性能,这对于追求高帧率和低延迟的游戏来说至关重要。本文将详细介绍使用 C 进行游戏开发的基础知识和技术要点ÿ…...
三、大模型(LLMs)微调面
本文精心汇总了多家顶尖互联网公司在大模型基础知识考核中的核心考点,并针对这些考点提供了详尽的解答。并提供电子版本,见于文末百度云盘链接中,供读者查阅。 一、大模型微调 • 1 如果想要在某个模型基础上做全参数微调,究竟需要…...
Flutter升级与降级
升级 版本升级 // 升级到指定版本flutter upgrade 版本号// 升级到最新版本flutter upgrade 降级 1.需要先确定想要降级的版本号。 2.切换到系统安装Flutter的目录 3.在https://github.com/flutter/flutter,找到要回退的版本号对应的commit序号(具…...
分布式并发场景的核心问题与解决方案
文章目录 分布式并发场景的核心问题与解决方案一、核心问题分析1. 分布式事务问题2. 数据一致性问题3. 并发控制问题4. 分布式锁失效问题 二、解决方案1. 分布式事务解决方案1.1 可靠消息最终一致性方案1.2 TCC方案实现 2. 缓存一致性解决方案2.1 延迟双删策略2.2 Canal方案 3.…...
D - Many Segments 2(ABC377)
题意:给定n和m,给定n个区间li,ri,求出满足区间lr不完全包含区间liri的个数 分析:用优先队列对区间r进行排序,i表示左区间,每次找到右区间加入即可。 代码: #include<bits/stdc…...
数组指针和指针数组的区别
数组指针和指针数组的区别 根据我个人的理解如下: 数组指针:指向数组的指针。着重点在于最后的指针两个字。 指针数组: 所有元素都是指针的数组。着重点在于最后的数组两个字。 另外来看助手的回答: Kimi: 1. **数组指针(Ar…...
【VUE点击父组件按钮,跳转到子组件】
要实现在Vue中,父组件通过点击按钮进入子组件的 <el-dialog> 弹窗,并在弹窗中嵌套 <el-table> 表格,可以按照以下步骤进行编写代码: 在父组件中,定义一个数据属性用于控制子组件弹窗的显示与隐藏。 data…...
Java列表排序:方法与实践
在Java编程中,列表排序是一个常见且重要的任务。本文将介绍Java中对列表进行排序的几种方法,包括使用Collections.sort()、List.sort()以及自定义排序规则。 1. 使用Collections.sort() Collections.sort()是Java提供的一个静态方法,用于对…...
哈希及其封装实现unordermap和set
哈希 直接定址法 哈希和之前的红黑树的区别就是,它是通过映射关系来找到目标的,可以把它想象成之前排序的计数排序,那其实就是哈希的一种方法,叫做直接定址法。 对于比较集中的数据,它只需要开一段区间,…...
在 AMD GPU 上构建解码器 Transformer 模型
Building a decoder transformer model on AMD GPU(s) — ROCm Blogs 2024年3月12日 作者 Phillip Dang. 在这篇博客中,我们展示了如何使用 PyTorch 2.0 和 ROCm 在单个节点上的单个和多个 AMD GPU 上运行Andrej Karpathy’s beautiful PyTorch re-implementation …...
Canvas简历编辑器-选中绘制与拖拽多选交互设计
Canvas简历编辑器-选中绘制与拖拽多选交互设计 在之前我们聊了聊如何基于Canvas与基本事件组合实现了轻量级DOM,并且在此基础上实现了如何进行管理事件以及多层级渲染的能力设计。那么此时我们就依然在轻量级DOM的基础上,关注于实现选中绘制与拖拽多选交…...
简单工厂(Simple Factory)
简单工厂(Simple Factory) 在创建一个对象时不向客户暴露内部细节,并提供一个创建对象的通用接口。 说明: 简单工厂把实例化的操作单独放到一个类中,这个类就成为简单工厂类,让简单工厂类来决定应该用哪…...
ffmpeg拉流分段存储到文件-笔记
通过ffmpeg可以从rtsp网络流拉取数据并存储到本地文件里,如下命令。做个笔记 ffmpeg -rtsp_transport tcp -i rtsp://192.168.1.168:6880/live -c copy -f segment -segment_time 60 stream_piece_%d.mp4这条 ffmpeg 命令的作用是从一个 RTSP 流中捕获视频ÿ…...
Java 实习工资大概是多少?——解读影响薪资的因素
文章目录 1. 城市因素:一线、二线的差距2. 公司类型:互联网公司、外企和传统企业的差别3. 个人能力:经验、技术栈的重要性4. 其他影响因素:学历和实习时间总结推荐阅读文章 Java 开发作为广泛应用的职业方向,实习工资的…...
【Linux】万字详解:Linux文件系统与软硬链接
🌈 个人主页:Zfox_ 🔥 系列专栏:Linux 目录 🚀 前言 一: 🔥 磁盘的物理结构二: 🔥 磁盘的存储结构 三: 🔥 磁盘的逻辑结构 四: &#…...
spacenavd
介绍spacenavd开源项目,主要是因为在斯坦福大学的UMI项目中使用了该项目。在斯坦福大学的 UMI(Universal Manipulation Interface)项目中,Spacenavd 主要用于处理 3D Space Mouse(空间鼠标)的输入…...
C#WPF的XAML的语法详谈和特性
WPF的XAML(eXtensible Application Markup Language)是一种基于XML的标记语言,用于在.NET框架中定义和描述用户界面。XAML提供了一种声明性的方式来构建应用程序的UI元素,包括窗口、控件、布局、样式、动画和数据绑定等。 XAML的…...
一篇文章讲透数据结构之二叉搜索树
前言 在前面的学习过程中,我们已经学习了二叉树的相关知识。在这里我们再使用C来实现一些比较难的数据结构。 这篇文章用来实现二叉搜索树。 一.二叉搜索树 1.1二叉搜索树的定义 二叉搜索树(Binary Search Tree)是基于二叉树的一种升级版…...
新手入门c++(8)
到时候了,是时候给你们讲一下其他的定义形式与格式化输入输出了。 1.长整型变量 长整型变量分为两种: ①long类型 在计算机编程中,long 类型是一个整型数据类型,用于存储较大的整数。它的大小和范围取决于操作系统和编译器的实…...
新手铲屎官提问,有哪几款噪音低的宠物空气净化器推荐
相信很多铲屎官都明白的的痛就是猫咪掉毛太严重,所以每次看到满天飞的浮毛时只想赶紧逃离,一点都不想清理。但是家是自己的,猫是自己的,健康也是自己的,不清理也得清理。 为了更有效的清理浮毛,我朋友特意…...
解决RabbitMQ脑裂问题
文章目录 前言一、现象二、解决办法 前言 RabbitMQ脑裂 一、现象 RabbitMQ镜像群出现脑裂现象,各个节点的MQ实例都“各自为政”,数据并不同步。 二、解决办法 # 停止mq sh rabbitmq-server stop_app # 查看mq进程是否存在 ps -ef | grep rabbitmq # …...
经纬恒润AUTOSAR成功适配芯钛科技Alioth TTA8车规级芯片
在汽车电子领域,功能安全扮演着守护者的角色,它确保了车辆在复杂多变的情况下保持稳定可靠的运行。随着汽车电子的复杂性增加,市场对产品功能安全的要求也日益提高。基于此背景,经纬恒润AUTOSAR基础软件产品INTEWORK-EAS-CP成功适…...
4、java random随机数、一维数组、二维数组
目录 Random类与随机数生成数组的概述与使用数组的内存分配与访问数组的常见问题与解决方案一维数组的遍历与操作二维数组的概述与遍历1. Random类与随机数生成 引言 在编程中,我们经常需要生成随机数,比如在游戏、模拟实验或者数据处理中。Java提供了一个非常方便的类Rand…...
C++ 魔法三钥:解锁高效编程的封装、继承与多态
快来参与讨论💬,点赞👍、收藏⭐、分享📤,共创活力社区。 目录 💯前言 💯封装 1.封装概念 2.封装格式 3.封装的原理 4.封装的作用 💯继承 1.继承的概念 2.继承格式 3.继承的…...
姿态传感器(学习笔记上)
上节我们学的是温湿传感器,这节我们学的是姿态传感器,虽然都是传感器,但是它们还是有很大的区别的,这节的传感器我们通过学习可知,开发板上的姿态传感器型号是QMI8658C,内部集成3轴加速度传感器和3轴陀螺仪…...
labelimg使用教程
快捷键 W:调出标注的十字架,开始标注 A:切换到上一张图片 D:切换到下一张图片 del:删除标注的矩形框 CtrlS:保存标注好的标签 Ctrl鼠标滚轮:按住Ctrl,然后滚动鼠标滚轮,…...
永嘉县住房和城乡建设局网站/百度关键词排名优化工具
转眼间已是十月了,小伙伴都在努力复习,2021准备考研的考生也在认真复习,每年考研人数都是增加的吗?今年有什么变化吗?小编整理“2021考研:推免生处境尴尬,考研还是推免?”文章&#…...
微信的微网站模板下载不了/淘客推广怎么做
王姐手下,经营着一个女装店,有5、6年了。手上有不少老客户,但是生意一直不温不火,平平淡淡。赔钱不至于,但是发不了财。 她店里的女装,进货价在300到600之间,卖价1000多2000,利润空…...
上海市公安网站备案查询/搜搜
一、常见垃圾收集器 现在常见的垃圾收集器有如下几种: 新生代收集器: SerialParNewParallel Scavenge 老年代收集器: Serial OldCMSParallel Old 堆内存垃圾收集器:G1 每种垃圾收集器之间有连线,表示他们可以搭…...
wordpress博客修改/免费个人自助建站
对于oracle日志组来说,每组日志最少一个成员,如果这个成员被破坏了会导致整个日志组都不可以被访问了,在数据库启动还有数据库要访问这组日志的时候会失败。为了避免这种情况要保证每组日志成员至少两个以上,不同的成员要放在不同…...
松江郑州阳网站建设/学生个人网页制作html代码
摘 要即时通讯软件即所谓的聊天工具,其主要用途是用于文字信息的传递与文件传输。使用ECLIPSE作为即时通讯软件的开发工具,使用Socket建立通讯渠道,多线程实现多台计算机同时进行信息的传递,SWING技术等进行实际开发相对比较合适。…...
手机网站建设推广/杭州关键词排名工具
下面是我最近总结的一点点东西而已,以后还会更多1、.时间linux系统在时间上有比较多的东西。在游戏里,时间是一个非常重要的一个变量,涉及到前后端时间同步,游戏业务的倒计时,心跳等等的一系列功能点等等,如…...