layout: post

categories: Java

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

tagline: by 子悠

tags:

  • 子悠

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

不可变类

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

  1. package com.example.demo.immutable;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import java.util.List;
  5. import java.util.Map;
  6. public final class Teacher {
  7. private final String name;
  8. private final List<String> students;
  9. private final Address address;
  10. private final Map<String, String> metadata;
  11. public Teacher(String name, List<String> students, Address address, Map<String, String> metadata) {
  12. this.name = name;
  13. this.students = students;
  14. this.address = address;
  15. this.metadata = metadata;
  16. }
  17. public String getName() {
  18. return name;
  19. }
  20. public List<String> getStudents() {
  21. return new ArrayList<>(students);
  22. // return students;
  23. }
  24. public Address getAddress() {
  25. // return address;
  26. return address.clone();
  27. }
  28. public Map<String, String> getMetadata() {
  29. return new HashMap<>(metadata);
  30. // return metadata;
  31. }
  32. }

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

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

  1. package com.example.demo.immutable;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import java.util.List;
  5. import java.util.Map;
  6. public record Teacher(String name, List<String> students, Address address, Map<String, String> metadata) {
  7. @Override
  8. public List<String> students() {
  9. return new ArrayList<>(students);
  10. // return students;
  11. }
  12. @Override
  13. public Address address() {
  14. // return address;
  15. return address.clone();
  16. }
  17. @Override
  18. public Map<String, String> metadata() {
  19. return new HashMap<>(metadata);
  20. // return metadata;
  21. }
  22. }

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

Record 关键字

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

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

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

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

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

  1. public static Teacher of() {
  2. return new Teacher("Java极客技术", new ArrayList<>(), new Address(), new HashMap<>());
  3. }
  4. public static Teacher of(String name) {
  5. return new Teacher(name, new ArrayList<>(), new Address(), new HashMap<>());
  6. }

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

  1. Teacher teacher = Teacher.of();

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

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

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

总结

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

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

Java 中你绝对没用过的一个关键字?的更多相关文章

  1. 关于Java中的继承和组合的一个错误使用的例子

    [TOC] 关于Java中的继承和组合的一个错误使用的例子 相信绝大多数人都比较熟悉Java中的「继承」和「组合」这两个东西,本篇文章就主要就这两个话题谈论一下.如果我某些地方写的不对,或者比较幼稚, ...

  2. Java中创建对象的5种方式 &&new关键字和newInstance()方法的区别

    转载:http://www.kuqin.com/shuoit/20160719/352659.html 用最简单的描述来区分new关键字和newInstance()方法的区别:newInstance: ...

  3. 浅谈java中源码常见的几个关键字(native,strictfp,transient,volatile)

    最近看源码总发现一些没见过的关键字,今天就来整理一下native,strictfp,transient,volatile native 本地 native是与C++联合开发的时候用的!java自己开发 ...

  4. Java中的覆盖和隐藏以及final关键字

    Java覆盖和隐藏 (1) 变量只能被隐藏(包括静态和非静态),不能被覆盖: (2) 可以用子类的静态变量隐藏父类的静态变量,也可以用子类的非静态变量隐藏父类的静态变量,也可以用非最终变量(final ...

  5. Java中的策略模式,完成一个简单地购物车,两种付款策略实例教程

    策略模式是一种行为模式.用于某一个具体的项目有多个可供选择的算法策略,客户端在其运行时根据不同需求决定使用某一具体算法策略. 策略模式也被称作政策模式.实现过程为,首先定义不同的算法策略,然后客户端把 ...

  6. Java中的多表&事务&DCL&一个多表操作例子

    准备sql: 创建部门表 CREATE TABLE dept( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(20) ); INSERT INTO d ...

  7. java中JDBC当中请给出一个DataSource的HelloWorld例子

    在前面 的jdbc的Helloworld程序当中,我们用DriverManager来获取数据库连接.事实上通过这种方法获取数据库连接,是比较耗费计算机资 源的.当然了,这也是没有办法的事儿.就像我们买 ...

  8. java中构造方法和this,static关键字

    构造方法: 构造方法是一种特殊的方法,用于创建该类的对象,对对象的数据进行初始化 格式如下: [修饰符] 类名(形参列表){ 方法体 } 特点 A:方法名和类名相同  B:没有返回值类型,连void都 ...

  9. java中的标识符、修饰符、关键字

    关键字的特点:1.完全小写的字母,2,在增强版记事本中有特殊颜色 例如@是电子邮箱当中有特殊含义的.被保留的.不能随意使用的字符,关键字. 例如图中public.class.static.void是关 ...

  10. java中的断言

     断言:也就是所谓的assertion,是jdk1.4后加入的新功能. 它主要使用在代码开发和测试时期,用于对某些关键数据的判断,如果这个关键数据不是你程序所预期的数据,程序就提出警告或退出. 当软件 ...

随机推荐

  1. Go工程化 - 依赖注入

    我们在微服务框架kratos v2的默认项目模板中kratos-layout使用了google/wire进行依赖注入,也建议开发者在维护项目时使用该工具. wire 乍看起来比较违反直觉,导致很多同学 ...

  2. k8s 中的 Pod 细节了解

    k8s中Pod的理解 基本概念 k8s 为什么使用 Pod 作为最小的管理单元 如何使用 Pod 1.自主式 Pod 2.控制器管理的 Pod 静态 Pod Pod的生命周期 Pod 如何直接暴露服务 ...

  3. 优化过的containerd配置文件:config.toml

    disabled_plugins = [] imports = [] oom_score = 0 plugin_dir = "" required_plugins = [] roo ...

  4. EFK-1:快速指南

    转载自:https://mp.weixin.qq.com/s?__biz=MzUyNzk0NTI4MQ==&mid=2247483801&idx=1&sn=11fee5756c ...

  5. Pod的滚动升级过程

  6. Linux make编译

    安装问题 linux编译流程 linux开发部分 一般来说著名的linux系统基本上分两大类: RedHat系列:Redhat.Centos.Fedora等 Debian系列:Debian.Ubunt ...

  7. 我的 Kafka 旅程 - 性能调优

    Producer 于 config/producer.properties 配置文件中的项 # 序列化数据压缩方式 [none/gzip/snappy/lz4/zstd] compression.ty ...

  8. cf1082 A. Vasya and Book

    中文题意: 思路:我们先看看能不能直接从x翻到y,abs(y-x)%d==0,可以就直接输出abs(y-x)/d咯,不行的话之后有2种操作 1.先翻回到第一页,从第一页看看能不能范到y,不能的话翻到最 ...

  9. 【机器学习】利用 Python 进行数据分析的环境配置 Windows(Jupyter,Matplotlib,Pandas)

    环境配置 安装 python 博主使用的版本是 3.10.6 在 Windows 系统上使用 Virtualenv 搭建虚拟环境 安装 Virtualenv 打开 cmd 输入并执行 pip inst ...

  10. 记一次 .NET 某工控视觉软件 非托管泄漏分析

    一:背景 1.讲故事 最近分享了好几篇关于 非托管内存泄漏 的文章,有时候就是这么神奇,来求助的都是这类型的dump,一饮一啄,莫非前定.让我被迫加深对 NT堆, 页堆 的理解,这一篇就给大家再带来一 ...