目录
- 一、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或者性别不符合"); } } @Override public 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 { @Override public String eat() { return name+"吃鱼"; } } public record Dog(String name) implements Animal { @Override public 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){ //声明一个本地Record record 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方法