jdk17新特性—— record关键字(类似于Lombok功能)

一、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方法

    在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小志的博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值