从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(空间鼠标)的输入…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...
数据挖掘是什么?数据挖掘技术有哪些?
目录 一、数据挖掘是什么 二、常见的数据挖掘技术 1. 关联规则挖掘 2. 分类算法 3. 聚类分析 4. 回归分析 三、数据挖掘的应用领域 1. 商业领域 2. 医疗领域 3. 金融领域 4. 其他领域 四、数据挖掘面临的挑战和未来趋势 1. 面临的挑战 2. 未来趋势 五、总结 数据…...
基于Python的气象数据分析及可视化研究
目录 一.🦁前言二.🦁开源代码与组件使用情况说明三.🦁核心功能1. ✅算法设计2. ✅PyEcharts库3. ✅Flask框架4. ✅爬虫5. ✅部署项目 四.🦁演示效果1. 管理员模块1.1 用户管理 2. 用户模块2.1 登录系统2.2 查看实时数据2.3 查看天…...
Python爬虫(四):PyQuery 框架
PyQuery 框架详解与对比 BeautifulSoup 第一部分:PyQuery 框架介绍 1. PyQuery 是什么? PyQuery 是一个 Python 的 HTML/XML 解析库,它采用了 jQuery 的语法风格,让开发者能够用类似前端 jQuery 的方式处理文档解析。它的核心特…...
【笔记】结合 Conda任意创建和配置不同 Python 版本的双轨隔离的 Poetry 虚拟环境
如何结合 Conda 任意创建和配置不同 Python 版本的双轨隔离的Poetry 虚拟环境? 在 Python 开发中,为不同项目配置独立且适配的虚拟环境至关重要。结合 Conda 和 Poetry 工具,能高效创建不同 Python 版本的 Poetry 虚拟环境,接下来…...
安宝特方案丨从依赖经验到数据驱动:AR套件重构特种装备装配与质检全流程
在高压电气装备、军工装备、石油测井仪器装备、计算存储服务器和机柜、核磁医疗装备、大型发动机组等特种装备生产型企业,其产品具有“小批量、多品种、人工装配、价值高”的特点。 生产管理中存在传统SOP文件内容缺失、SOP更新不及、装配严重依赖个人经验、产品装…...
