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

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

前面的文章给大家介绍了如何自定义一个不可变类,没看过的小伙伴建议去看一下,这节课给大家介绍一个 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<String> students;
  private final Address address;
  private final Map<String, String> metadata;

  public Teacher(String name, List<String> students, Address address, Map<String, String> metadata){
    this.name = name;
    this.students = students;
    this.address = address;
    this.metadata = metadata;
  }

  public String getName(){
    return name;
  }

  public List<String> getStudents(){
    return new ArrayList<>(students);
//    return students;
  }

  public Address getAddress(){
//    return address;
    return address.clone();
  }

  public Map<String, String> getMetadata(){
    return new HashMap<>(metadata);
//    return metadata;
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.

如果你复制上面代码到 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<String> students, Address address, Map<String, String> metadata){

  @Override
  public List<String> students(){
    return new ArrayList<>(students);
//    return students;
  }

  @Override
  public Address address(){
//    return address;
    return address.clone();
  }

  @Override
  public Map<String, String> metadata(){
    return new HashMap<>(metadata);
//    return metadata;
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.

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

图片

Record 关键字

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

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

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

public record Teacher(String name, List<String> students, Address address, Map<String, String> metadata){
}//1,2
 Teacher teacher = new Teacher("Java极客技术", students, address, metadata);//3
  • 1.
  • 2.
  • 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<>());
  }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

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

 Teacher teacher = Teacher.of();
  • 1.

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

  public Teacher {
    if (null == students || students.size() == 0) {
      throw new IllegalArgumentException();
    }
  }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

图片

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

总结

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

责任编辑:武晓燕 来源: Java极客技术
相关推荐

2017-07-26 10:08:06

FABDesign SuppAndroid

2022-07-20 07:29:52

Java

2021-01-03 16:12:35

Java工具开发

2024-08-19 02:00:00

FunctionJava8接口

2024-09-05 09:30:51

FunctionJava8接口

2020-11-04 10:31:29

Jupyter NotPython数据分析

2019-06-26 10:10:44

Linux终端命令

2020-10-20 18:51:43

C++IDECode

2022-04-19 08:50:43

Java8接口

2024-03-15 08:18:25

volatileAtomic关键字

2017-03-22 19:52:16

Devops开源

2020-01-17 20:00:25

SQL函数数据库

2021-06-24 09:08:34

Java代码泛型

2024-04-19 09:02:32

前端调试技巧

2023-12-11 13:59:00

YieldPython生成器函数

2024-03-26 00:48:38

2012-06-02 00:53:39

Javafinally

2020-08-10 08:00:13

JavaFinal关键字

2018-09-27 15:58:06

MySQL数据库性能优化

2012-06-07 16:16:43

JavaScript
点赞
收藏

51CTO技术栈公众号