目录
- 一、record关键字的概述
- 1.1、概述
- 1.2、特性
- 二、record关键字的代码示例
- 2.1、record关键字代码示例
- 2.2、record关键字代码.class文件示例
- 2.3、record关键字代码示例 总结说明
- 三、record关键字实现密封接口的代码示例
- 3.1、record关键字实现密封接口的代码示例
- 四、record关键字定义一个本地的record的代码示例
- 4.1、record关键字定义一个本地的record的代码示例
- 五、record关键字支持使用注解的代码示例
- 5.1、record关键字支持使用注解的代码示例
一、record关键字的概述
1.1、概述
- record为定义class提供了一种紧凑的语法,被record定义的类是浅不可变数据的透明持有者。
- 浅不可变数据是指这样的一种类,它们用来描述一种简单的数据结构,这种数据结构的属性都是final不可变的(即状态不可变)。
- 因为final字段只是不能对变量重复赋值,变量引用的对象本身是有可能可以被修改的,比如这个状态是一个集合的话,向集合中添加/删除元素等操作是可以的。
1.2、特性
- JDK14的JEP 359: Records (Preview)引入;
- JDK15的JEP 384: Records (Second Preview)进行了第二轮预览;
- JDK16的JEP 395:Records转正。
二、record关键字的代码示例
2.1、record关键字代码示例
-
创建Student的record代码示例
package com.xz.jdk17.day4;public record Student(int id,String name, int sex) implements Comparable<Student>{/*** 构造函数可以声明为没有正式形参列表的形式,此时默认使用完整的状态参数列表* 允许构造函数只执行参数的验证和规范化,而省略显式的字段初始化。*/public Student {if(id< 0 ||sex >1){throw new RuntimeException("id或者性别不符合");}}@Overridepublic int compareTo(Student o) {return 0;}}
-
创建StudentGroup的record代码示例
package com.xz.jdk17.day4;import java.util.List;public record StudentGroup(List<Student> studentList,String groupName) {}
-
测试类代码示例
package com.xz.jdk17.day4;import java.util.Arrays; import java.util.List; import java.util.stream.Collectors;/*** @Author: xz* @Date: 2024-02-02 19:31* @Description:*/ public class Test {public static void main(String[] args) {Student student1 = new Student(1, "张三", 0);Student student2 = new Student(1, "张三", 0);System.out.println("id:"+student1.id()+",name:"+student1.name()+",sex:"+student1.sex());System.out.println(student1.hashCode());System.out.println(student1.equals(student2));System.out.println(student1.toString());List<Student> studentList = Arrays.stream(new Student[]{student1,student2}).collect(Collectors.toList());StudentGroup studenGroup = new StudentGroup(studentList, "group");System.out.println(studenGroup.toString());studenGroup.studentList().add(new Student(2, "李四", 1));System.out.println(studenGroup.toString());} }
-
测试结果
2.2、record关键字代码.class文件示例
-
创建Student的record代码的.class文件示例
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) //package com.xz.jdk17.day4;public record Student(int id, String name, int sex) implements Comparable<Student> {public Student(int id, String name, int sex) {if (id >= 0 && sex <= 1) {this.id = id;this.name = name;this.sex = sex;} else {throw new RuntimeException("id或者性别不符合");}}public int compareTo(Student o) {return 0;}public int id() {return this.id;}public String name() {return this.name;}public int sex() {return this.sex;} }
-
创建StudentGroup的record代码的.class文件示例
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) //package com.xz.jdk17.day4;import java.util.List;public record StudentGroup(List<Student> studentList, String groupName) {public StudentGroup(List<Student> studentList, String groupName) {this.studentList = studentList;this.groupName = groupName;}public List<Student> studentList() {return this.studentList;}public String groupName() {return this.groupName;} }
2.3、record关键字代码示例 总结说明
- record关键字类似enum,也是一种特殊的class。
- record会自动生成一个隐式的带参构造方法,默认没有无参构造方法,但record允许声明没有参数列表的构造方法,默认使用完整的状态参数列表,这允许构造函数只执行参数的验证和规范化,而省略显式的字段初始化。
- record会自动为每个状态生成一个同名的get方法,注意方法名与变量名同名,不是getXxx。都是final字段自然没有set方法。
- record会自动根据状态字段重写hashcode、equals以及toString方法。
- record没有extend子句,所有record都直接继承java.lang.Record,但可以实现接口。
- record是隐式final的,不能有抽象方法,不可再被继承,以防止被子类扩展方法改变状态。
- record不能定义native方法,以防止record记录的状态被外部行为影响。
三、record关键字实现密封接口的代码示例
3.1、record关键字实现密封接口的代码示例
-
record关键字实现密封接口的代码示例
public sealed interface Animal permits Cat, Dog{String eat(); }public record Cat(String name) implements Animal {@Overridepublic String eat() {return name+"吃鱼";} }public record Dog(String name) implements Animal {@Overridepublic String eat() {return name+"吃骨头";} }
四、record关键字定义一个本地的record的代码示例
4.1、record关键字定义一个本地的record的代码示例
-
record关键字定义一个本地的record的代码示例
public class Test1 {public static void main(String[] args) {List<String> list=new ArrayList<>();list.add("1");list.add("2");list.add("3");List<Integer> integers = get(list);System.out.println(integers);}public static List<Integer> get(List<String> list){//声明一个本地Recordrecord NumberRecord(String numberstr,int number){}return list.stream().map(num ->new NumberRecord(num, Integer.parseInt(num))).sorted((n1,n2)->Integer.compare(n2.number(),n1.number())).map(NumberRecord::number).collect(Collectors.toList());} }
-
输出结果
五、record关键字支持使用注解的代码示例
5.1、record关键字支持使用注解的代码示例
-
record关键字支持使用注解的代码示例
public record Dept(@Deprecated int id,@Deprecated String deptName) {}
-
对应的反编译代码如下,可以看到注解会被用于修饰构造方法的对应参数,以及字段的get方法