行业知识
Java record类用法简介
2026-10-26 15:25:17
来源:互联网转载
参考资料
- Java 16 新特性:record类
- 新特性Record最全用法总结—动力节点总结
- Javaのレコードクラス
- 从头学Java17-Stream API(二)结合Record、Optional
目录
- 一. 介绍
- 二. 基本语法
- 三. 各种特性示例
- 3.1 准备
- 3.2 创建,属性,方法,内部record类
- 3.3 反射
- 3.4 记录模式(Record Patterns)
- 3.5 组件属性浅层不可变
- 四. 适用场景
一. 介绍
- 是一种特殊的java类,在Java16中正式出现,用于创建一个不可变的类。该类一经创建并赋值后,就不可再改变了。
- 类以及所有的属性都是final修饰的, Record类不能被继承。
- 可用于创建一个简单的数据传输对象(DTO),用来传输数据。
- record类会自动生成,全参构造方法,hashCode()方法,equals()方法,toString()方法和用来获取数据的方法。
- 注意,在record类对象创建后,只能get数据,无法set数据,这一点和普通的POJP不同。
- 在只读取数据的场景中,可以代替lombok。
二. 基本语法
- 支持实现接口,不支持继承
- 支持静态变量,静态代码块,静态方法
- 支持注解
- 不支持成员变量和初始化代码块
- 可内部嵌套record,嵌套的record是static状态的
- 内部record只能访问外部record的静态方法和变量
- 可通过反射来获取record的信息
⏹基本构造示例
三. 各种特性示例
3.1 准备
⏹接口
public interface S002Api {Map getS001Data();}⏹创建一个record类,该类有内部record类,并且实现了接口
import java.util.List;import java.util.Map;import org.springframework.util.ObjectUtils;public record StudentRecord(Integer id, String name, List addressList) implements S002Api {// 静态变量public static Integer money;// 只允许静态变量,成员变量变量会报错// String food = "汉堡";// 不支持初始化代码块/* { }*/// 静态代码块static {money = 100;}// 构造方法的简单写法,若在赋值时,不需要进行二次数据处理,可以简化为下面这种写法// record会给我们自动赋值public StudentRecord {// 在构造对象时,对数据进行校验if (ObjectUtils.isEmpty(addressList)) {throw new RuntimeException("addressList不能为空");}}// 静态方法public static void printMsg1() {System.out.println("Hello world! printMsg1");}// 非静态方法public void printMsg2() {System.out.println("Hello world! printMsg2");}// 实现接口中的方法@Overridepublic Map getS001Data() {return Map.of("key1", "value1");}// record类的内部可以嵌套record类,该类是静态类,static可省略public static record InfoRecord(String car, String pet) {// record类默认会生成构造方法,但我们可以根据需要对其进行修改public InfoRecord(String car, String pet) {this.car = "/__" + car + "__/";this.pet = "/__" + pet + "__/";}public String getMsg() {// 因为内部record类是static的,所以只能调用外部record类中的静态方法printMsg1();// printMsg2();return "{num: 10}";}}}3.2 创建,属性,方法,内部record类
public void run(String... args) throws Exception { // 创建Record类对象 StudentRecord studentRecord1 = new StudentRecord(120, "Jmw", List.of("地球", "宇宙")); System.out.println(studentRecord1); // StudentRecord[id=120, name=Jmw, addressList=[地球, 宇宙]] // 调用静态方法 StudentRecord.printMsg1(); // Hello world! printMsg1 // 调用非静态方法 studentRecord1.printMsg2(); // Hello world! printMsg1 // 获取静态变量 System.out.println(StudentRecord.money); // 100 // 获取类的属性 System.out.println(studentRecord1.id()); // 120 System.out.println(studentRecord1.addressList()); // [地球, 宇宙] // 创建内部Record类对象 InfoRecord infoRecord = new StudentRecord.InfoRecord("丰田", "狗"); System.out.println(infoRecord); // InfoRecord[car=/__丰田__/, pet=/__狗__/] // 获取内部Record的方法 String msg = infoRecord.getMsg(); System.out.println(msg); // {num: 10}}3.3 反射
public void run(String... args) throws Exception { // 创建一个Record类,因为Record类实现了S002Api接口,所以类型可以指定为S002ApiS002Api s002ApiObj = new StudentRecord(130, "Fyh", List.of("银河", "火星"));// 判断是否是Record类boolean isRecord = s002ApiObj.getClass().isRecord();System.out.println(isRecord); // true// 获取该Record上所有的ComponentRecordComponent[] recordComponents = s002ApiObj.getClass().getRecordComponents();for (RecordComponent recordComponent : recordComponents) {System.out.println(recordComponent);}/*java.lang.Integer idjava.lang.String namejava.util.List addressList*/}3.4 记录模式(Record Patterns)
- 配合instanceof使用,用于类型转换时,直接获取组件值(属性值)
- 类似于JavaScript中的解构赋值
public void run(String... args) throws Exception { // 通过反射S002Api s002ApiObj = new StudentRecord(130, "Fyh", List.of("银河", "火星"));// 将接口转换为Record对象之后,才能通过转换之后的对象获取if(s002ApiObj instanceof StudentRecord) {// 手动进行对象转换StudentRecord obj = (StudentRecord)s002ApiObj;System.out.println(obj.id()); // 130System.out.println(obj.name()); // FyhSystem.out.println(obj.addressList()); // [银河, 火星]}// Java21中的新语法,类似于javascript中的解构赋值if(s002ApiObj instanceof StudentRecord(Integer id, String name, List addressList)) {System.out.println(id); // 130System.out.println(name); // FyhSystem.out.println(addressList); // [银河, 火星]}}3.5 组件属性浅层不可变
- 组件类型为基本数据类型的时候,不可变。
- 若类型为引用类型的话,深层是可变的。
public void run(String... args) throws Exception { // 定义一个简单的recordrecord JmwInfo(String id, String[] address) {};JmwInfo jmwInfo = new JmwInfo("10", new String[] {"地球", "月球"});// 在编译阶段就报错,无法被修改// jmwInfo.id = "20";System.out.println(jmwInfo.address[0]); // 地球jmwInfo.address[0] = "日本";System.out.println(jmwInfo.address[0]); // 日本}四. 适用场景
- 作为数据载体,例如DTO,VO等
- 适用于函数式编程
⏹有如下字符串,现在要求转换为java对象,保留20以上的,姓相同的分在一组
String teacherInfo = """ 张三,18 李四,20 王五,19 赵六,20 张四,22 张之维,100 王八,15 """;
public void run(String... args) throws Exception { // 定义一个简单的recordrecord Teacher(String name, Integer age) {};// 根据换行符切割字符串String[] teacherArrays = teacherInfo.split("\n");// 构造Teacher对象的函数Function createTeacher = (line) -> {String[] split = line.split(",");// 在此处创建了record的Teacher类return new Teacher(split[0], Integer.parseInt(split[1]));};Map result = Arrays.stream(teacherArrays)// 先将数据处理为Teacher对象 .map(createTeacher) // 过滤出 >= 20 的数据 .filter(teacher -> teacher.age() >= 20) // 根据姓来分组 .collect(Collectors.groupingBy(teacher -> teacher.name.charAt(0)));System.out.println(result);/*{张=[Teacher[name=张四, age=22], Teacher[name=张之维, age=100]], 赵=[Teacher[name=赵六, age=20]], 李=[Teacher[name=李四, age=20]]}*/}
上一篇:hmcl认证服务器怎么找?
最新文章
- Zol下载攻略,轻松获取所需资源!
- 做过饭店两三年,过来进厂工作一年多,但现在想找工作,而不知做什么工作,想做销售,文员,可因为自己没有经验,不敢去尝试,你们有什么建议呢
- 上过的课怎么排序?
- 揭秘复利盘源码,掌握财富增值的神秘力量!
- 一键重装Win10系统,轻松掌握系统重装指南
- 揭秘汉字奥秘,你不知道的衤字发音探索?
- 淘宝扭蛋机小程序开发:探索无限惊喜的购物新体验
- 云服务器怎么接受数据?
- 三十岁,因为带孩子脱岗一年半。以前毕业就到私企做了HR,一做就是五年。后来家里没人帮忙带孩子只能自己辞职带。现在孩子上幼儿园想着找工作。专员人家不要,有五年经验说我不稳定。做主管又嫌弃拖孩子,下班要早不出差不加班。现在天天发愁,像我这样的能做什么,还是学习其他技能?
- 安卓服务器怎么升级到鸿蒙?