Java Record的使用场景分析

 更新时间:2025年06月20日 10:13:01   作者:麻辣香蝈蝈  
Java的Record用于简化不可变数据类定义,自动提供构造器、equals、hashCode等方法,字段默认final且不可变,适用于仅存储数据的场景,不支持手动添加非final字段,但允许扩展方法和静态成员,本文给大家介绍Java Record的使用,感兴趣的朋友一起看看吧

一、前言

  • 学习新特性Record的作用

二、学习内容:

  • Record与Class的区别以及Record使用场景

三、问题描述

  • 为什么引入Record以及Record的作用

四、解决方案:

4.1 为什么引入Record

Java 引入 record 的主要原因是为了简化创建不可变数据类的过程,并提高代码的可读性和维护性。

以下是一些具体的原因:

减少样板代码:

  • 🌟 record 自动生成构造器、equals()、hashCode() 和 toString() 方法,以及每个字段的 getter方法,这样开发人员就可以专注于业务逻辑而不是样板代码。

不可变性:

  • 🌟 record 的所有字段默认是 final 的,这意味着它们是不可变的。这有助于创建线程安全和易于管理的数据模型。

简洁性:

  • record 允许你用更少的代码来定义数据类,使得类的定义更加清晰和简洁。

性能优化:

  • record 类型可能🌟 受到编译器的特定优化,例如更有效的内存布局,从而可能带来性能上的提升。

模式匹配的支持:

  • record 在模式匹配方面有更好的支持,这在 Java 14 及以后的版本中变得更加重要,尤其是在使用结构化绑定和改进的 switch
    表达式时。

易于调试:

  • 由于 record 自动提供了 toString() 方法,因此在调试时可以更容易地查看对象的状态。

明确的意图:

  • 使用 record 明确地表明了类的目的是作为一个简单的数据载体,这对于其他开发人员阅读代码时是有帮助的。

4.2 Record与Class区别

  • 观察下面Class代码与Record代码的区别
  • Class
package org.example.recodes;
import java.util.Objects;
public class Cat {
    String name;
    public String getName() {
        return name;
    }
    public Cat(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                '}';
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        Cat cat = (Cat) o;
        return Objects.equals(name, cat.name);
    }
    @Override
    public int hashCode() {
        return Objects.hash(name);
    }
}
  • Record
package org.example.recodes;
public record RecordCat(String name) { }

🌟 上面两段代码是等效的

record 自动生成构造器、equals()、hashCode() 和 toString() 方法,以及每个字段的 getter方法

我们运行一下下面代码看看区别

package org.example.recodes;
public class Main {
    public static void main(String[] args) {
        Cat cat = new Cat("mimi");
        System.out.println(cat.getName());
        System.out.println(cat);
        RecordCat recordCat = new RecordCat("momo");
        System.out.println(recordCat.name());
        System.out.println(recordCat);
    }
}

结果如下:

4.3 语法与使用场景

适用于那些仅用于存储数据而没有复杂业务逻辑的情况
结构体里面可扩展内容如下

⭐️Record所有字段默认是final

  • 非静态字段:
  • 非静态字段 要通过构造器(隐式final)去创建,不能在结构体里面自定义
  • 你不能直接在 record 结构体中手动添加 final 的字段。
  • 如果你需要在结构体自定义的字段,推荐使用 class。
// 构造传入
public record Person(String name, int age) {  
    // 这是合法的,因为字段在声明中定义  
    // 不合法:不能再这里定义其他字段  
    // private final String address; // 这将导致编译错误  
    // 可以添加额外的方法  
    public String introduce() {  
        return String.format("My name is %s and I am %d years old.", name, age);  
    }  
}  
  • 实例方法:
  • 除了 record 自动生成的方法外,你可以添加自己的实例方法来扩展 record 的功能。这些方法可以实现特定的业务逻辑或操作。
  • 静态成员:
  • 你可以在 record 中添加静态方法,这些方法通常用于工厂模式,即创建 record 实例的替代构造方式。
  • 可以添加静态字段
  • 可以添加静态内部类
public record Person(String name, int age) {  
    // 静态字段  
    private static final String DEFAULT_COUNTRY = "Unknown";  
    // 静态方法  
    public static Person createDefaultPerson() {  
        return new Person("Anonymous", 0);  
    }  
    // 静态内部类  
    public static class PersonBuilder {  
        private String name;  
        private int age;  
        public PersonBuilder withName(String name) {  
            this.name = name;  
            return this;  
        }  
        public Person build() {  
            return new Person(name, age);  
        }  
    }  
    // 实例方法  
    public String introduce() {  
        return name + " is " + age + " years old";  
    }  
}  
// 使用示例  
public class Main {  
    public void example() {  
        // 使用静态方法  
        Person defaultPerson = Person.createDefaultPerson();  
        // 使用静态内部类  
        Person customPerson = new Person.PersonBuilder()  
            .withName("John")  
            .build();  
    }  
}  
  • 私有方法:
  • 私有方法可以用来封装 record 内部的实现细节,例如辅助计算或验证逻辑。
  • 嵌套类和内部类:
  • record 可以包含嵌套类和内部类,这些类可以用来定义相关的类型,比如枚举类型或其他辅助类。
  • 接口实现:
  • record 可以实现一个或多个接口,这样就可以提供接口中定义的方法的实现。
  • 注解:
  • record 可以使用注解来标记,这对于框架集成、元数据处理等非常有用。
  • 泛型:
  • record 支持泛型,允许你定义泛型参数,从而创建通用的 record 类型。
  • 覆盖默认方法:
  • 尽管 record 自动生成了一些方法,如 equals()、hashCode() 和toString(),你仍然可以覆盖这些方法以提供不同的实现。

五、总结:

5.1 场景使用

简单的数据使用

🌟 默认只有Getter方法

record Point(int x, int y) {
    // 无需显式定义构造器、equals()、hashCode() 或 toString()
}
public class Point {
    private final int x;
    private final int y;
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Point point = (Point) o;
        return x == point.x && y == point.y;
    }
    @Override
    public int hashCode() {
        return Objects.hash(x, y);
    }
    @Override
    public String toString() {
        return "Point{" +
                "x=" + x +
                ", y=" + y +
                '}';
    }
}

5.2 字段的定义

🌟 在 Java 记录中,所有字段都必须在记录的参数列表中定义。
🌟 记录是不可变的:字段一旦赋值,不能被修改。
🌟 无法在记录内部定义额外的 private final 字段。

下面是相关解释

隐式 final:

  • 所有记录字段默认是 final,这意味着它们一旦被初始化,就不能再被修改

只能通过构造器定义:

  • 记录中的字段必须在记录声明的紧随其后的参数列表中定义,不能在记录的体内再次定义或声明。
  • 这意味着无法手动添加如 private final 字段,直接在类体内定义是非法的。

自动构造器和访问器:

  • Java 会为记录自动生成构造器,以及每个字段的访问器方法(getter)。因此,您不需要手动编写 getter 方法。
public record Person(String name, int age) {  
    // 这是合法的,因为字段在声明中定义  
    // 不合法:不能再这里定义其他字段  
    // private final String address; // 这将导致编译错误  
    // 可以添加额外的方法  
    public String introduce() {  
        return String.format("My name is %s and I am %d years old.", name, age);  
    }  
}  
// 使用记录的主函数  
public class Main {  
    public static void main(String[] args) {  
        Person person = new Person("Alice", 30);  
        System.out.println(person.introduce()); // 输出:My name is Alice and I am 30 years old.  
    }  
}

(后续有遇到问题再添加)

到此这篇关于Java Record的使用 的文章就介绍到这了,更多相关java record使用 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • springboot启动流程过程

    springboot启动流程过程

    Spring Boot 简化了 Spring 框架的使用,通过创建 `SpringApplication` 对象,判断应用类型并设置初始化器和监听器,在 `run` 方法中,读取配置并加载到 `Environment` 中,通过 Spring 事件机制和 `EnvironmentPostProcessor` 处理配置
    2025-02-02
  • java多线程抓取铃声多多官网的铃声数据

    java多线程抓取铃声多多官网的铃声数据

    很容易就能发现通过改变 listId和page就能从服务器获取铃声的json数据, 通过解析json数据, 可以看到都带有{"hasmore":1,"curpage":1}这样子的指示,通过判断hasmore的值,决定是否进行下一页的抓取。 但是通过上面这个链接返回的json中不带有铃声的下载地址
    2016-04-04
  • java之StringBuffer常见使用方法解析

    java之StringBuffer常见使用方法解析

    这篇文章主要介绍了java之StringBuffer常见使用方法解析,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • Java经典面试题汇总:Mybatis

    Java经典面试题汇总:Mybatis

    本篇总结的是Mybatis框架相关的面试题,后续会持续更新,希望我的分享可以帮助到正在备战面试的实习生或者已经工作的同行,如果发现错误还望大家多多包涵,不吝赐教,谢谢
    2021-07-07
  • java实现短信通信的完整教程

    java实现短信通信的完整教程

    这篇文章主要为大家详细介绍了java实现短信通信的完整教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-05-05
  • Spring工作原理简单探索

    Spring工作原理简单探索

    这篇文章主要介绍了Spring工作原理简单探索,涉及Springaop与IOC,动态代理静态代理,反射等相关内容,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • Java生成表格图片的实例代码

    Java生成表格图片的实例代码

    这篇文章主要介绍了Java生成表格图片的实例代码,帮助大家更好的理解和学习Java,感兴趣的朋友可以了解下
    2020-09-09
  • SpringBoot 中 AutoConfiguration的使用方法

    SpringBoot 中 AutoConfiguration的使用方法

    这篇文章主要介绍了SpringBoot 中 AutoConfiguration的使用方法,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-04-04
  • idea 修改项目名和module名称的操作

    idea 修改项目名和module名称的操作

    这篇文章主要介绍了idea 修改项目名和module名称的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • Spring WebFlux的使用指南

    Spring WebFlux的使用指南

    这篇文章主要介绍了Spring WebFlux的使用指南,帮助大家更好的理解和学习使用Spring框架,感兴趣的朋友可以了解下
    2021-05-05

最新评论