• Java 中你绝对没用过的一个关键字?



    layout: post
    categories: Java
    title: Java 中你绝对没用过的一个关键字?
    tagline: by 子悠
    tags:

    • 子悠

    前面的文章给大家介绍了如何自定义一个不可变类,没看过的小伙伴建议去看一下,这节课给大家介绍一个 Java 中的一个关键字 Record,那 Record 关键字跟不可变类有什么关系呢?看完今天的文章你就知道了。友情提示 Record 关键字在 Java14 过后才支持的,所以是不是被阿粉说中了,还在使用 Java 8 的你一定没用过!

    不可变类

    我们先看一下之前定义的不可变类,代码如下。

    package com.example.demo.immutable;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    public final class Teacher {
      private final String name;
      private final List students;
      private final Address address;
      private final Map metadata;
    
      public Teacher(String name, List students, Address address, Map metadata) {
        this.name = name;
        this.students = students;
        this.address = address;
        this.metadata = metadata;
      }
    
      public String getName() {
        return name;
      }
    
      public List getStudents() {
        return new ArrayList<>(students);
    //    return students;
      }
    
      public Address getAddress() {
    //    return address;
        return address.clone();
      }
    
      public Map getMetadata() {
        return new HashMap<>(metadata);
    //    return metadata;
      }
    }
    
    

    如果你复制上面代码到 IDEA 中,并且刚好你的 JDK 版本是 Java14 之后的话,那么你就会看到下面这个提示,提示我们可以将 Teacher 这个不可变类转换为 Record。怎么样是不是很懵,没关系,我们按照提示操作一下看看会发生什么。

    点完之后我们的代码会变成下面的样子

    package com.example.demo.immutable;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    public record Teacher(String name, List students, Address address, Map metadata) {
    
      @Override
      public List students() {
        return new ArrayList<>(students);
    //    return students;
      }
    
      @Override
      public Address address() {
    //    return address;
        return address.clone();
      }
    
      @Override
      public Map metadata() {
        return new HashMap<>(metadata);
    //    return metadata;
      }
    }
    
    

    仔细一看你会发现,这是什么情况,record 是什么关键字,然后类名后面怎么还有参数?乍一看还以为变成一个方法了。此外我们之前的测试代码不用修改任何逻辑,照样可以正常运行,是不是很神奇?这就是 Record 关键字的特性。

    Record 关键字

    看完了 Record 关键字的 case ,我们来聊一下 Record 关键字是怎么用的,以及它有什么特性。

    1. Record 关键定义的类是不可变类;
    2. Record 定义的类需要将所有成员变量通过参数的形式定义;
    3. Record 定义的类默认会生成全部参数的构造方法;
    4. Record 定义的类中可以定义静态方法;
    5. Record 定义的类可以提供紧凑的方式进行参数校验;

    上面的五点里面前三点我们在之前的例子中都可以看出来,在定义和使用的时候可以明显的看到,如下所示。

    public record Teacher(String name, List students, Address address, Map metadata) {
    }//1,2
     Teacher teacher = new Teacher("Java极客技术", students, address, metadata);//3
    

    下面我们看下第四点和第五点,关于第四点我们可以在 Record 类中定义静态方法用来默认初始化对象,如下所示,通过这种方式我们可以写出更简洁的代码。

      public static Teacher of() {
        return new Teacher("Java极客技术", new ArrayList<>(), new Address(), new HashMap<>());
      }
    
      public static Teacher of(String name) {
        return new Teacher(name, new ArrayList<>(), new Address(), new HashMap<>());
      }
    

    在使用的时候,我们就可以直接通过类名引用静态方法就可以了,如下所示

     Teacher teacher = Teacher.of();
    

    接下来我们看看什么叫紧凑的方式进行参数校验,试想一下,如果我们需要校验在沟通 Teacher 对象的时候,student 成员变量不能为空,在我们以前的写法里面只要在构造方法里面进行一下判空就可以了,但是对于 Record 的形式,我们没有显示的创建构造方法,那我们应该如何进行判断呢?答案如下

      public Teacher {
        if (null == students || students.size() == 0) {
          throw new IllegalArgumentException();
        }
      }
    

    可以看到我们通过一种紧凑的构造方法的形式来进行了参数的校验,这种写法跟我们普通的构造方法是不一样的,没有方法参数,怎么样是不是很神奇。

    总结

    有的人说 JavaRecord 的新特性是为了让大家不使用 Lombok 的,阿粉倒是觉得不见得,毕竟 Lombok 用起来是真的香,而且 Record 也只能是定义不可变类,在某些情况下使用还是有局限性的,不可变类的使用场景并不是很多。

    更多优质内容欢迎关注公众号【Java 极客技术】,我准备了一份面试资料,回复【bbbb07】免费领取。希望能在这寒冷的日子里,帮助到大家。

  • 相关阅读:
    鸿蒙系统扫盲(二):再谈鸿蒙是不是安卓套壳?
    电话状态权限及IMEI获取流程源码分析
    在window环境下安装numpy模块(包)
    Oralce ORA-00018超出最大会话数处理记录
    C语言之字符函数&字符串函数篇(1)
    使用Python,Open3D对点云散点投影到面上并可视化,使用3种方法计算面的法向量及与平均法向量的夹角
    中国高等职业教育产业发展战略咨询与前景规划建议报告2022-2028年新版
    低代码:对开发人员可行吗
    基于SpringBoot的会员制医疗预约服务管理信息系统
    网站监控定时任务网址url监控神器
  • 原文地址:https://www.cnblogs.com/zi-you/p/16936858.html