跳转至

Java Record Type:深入理解与高效使用

简介

Java Record Type 是 Java 14 引入的一项新特性,旨在简化不可变数据类的创建。在以往,创建一个简单的不可变数据类需要编写大量样板代码,包括构造函数、访问器方法、equals()hashCode()toString() 等。Record Type 极大地减少了这种样板代码,让代码更加简洁、易读。

目录

  1. 基础概念
  2. 使用方法
    • 定义 Record
    • 创建实例
    • 访问字段
  3. 常见实践
    • 与传统类的对比
    • 在集合中的使用
  4. 最佳实践
    • 何时使用 Record
    • 与其他特性的结合
  5. 小结
  6. 参考资料

基础概念

Record 是一种特殊的类,它是不可变的,并且主要用于存储数据。它为类中的字段自动生成构造函数、访问器方法、equals()hashCode()toString() 等方法。Record 的字段在默认情况下是 final 的,并且只能通过构造函数进行初始化。

使用方法

定义 Record

定义一个 Record 非常简单,语法如下:

public record Person(String name, int age) {}

在上述示例中,Person 是一个 Record,它有两个字段:name(类型为 String)和 age(类型为 int)。编译器会自动为 Person Record 生成以下内容: - 一个包含所有字段的构造函数。 - 每个字段的访问器方法(例如,name()age())。 - equals()hashCode() 方法,基于字段的值进行比较和哈希计算。 - toString() 方法,以可读的方式输出 Record 的字段值。

创建实例

创建 Record 的实例与创建普通类的实例类似:

Person person = new Person("Alice", 30);

访问字段

可以使用自动生成的访问器方法来访问 Record 的字段:

String name = person.name();
int age = person.age();
System.out.println("Name: " + name + ", Age: " + age);

常见实践

与传统类的对比

传统类需要编写大量样板代码来实现不可变数据类的功能,例如:

public class TraditionalPerson {
    private final String name;
    private final int age;

    public TraditionalPerson(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        TraditionalPerson that = (TraditionalPerson) o;
        return age == that.age && Objects.equals(name, that.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    @Override
    public String toString() {
        return "TraditionalPerson{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

相比之下,Record 只需要一行代码就能实现相同的功能,代码更加简洁、易读。

在集合中的使用

Record 可以像普通类一样在集合中使用。例如,将 Person Record 对象存储在 List 中:

import java.util.ArrayList;
import java.util.List;

public class RecordInCollection {
    public static void main(String[] args) {
        List<Person> people = new ArrayList<>();
        people.add(new Person("Bob", 25));
        people.add(new Person("Charlie", 35));

        for (Person person : people) {
            System.out.println(person);
        }
    }
}

最佳实践

何时使用 Record

  • 简单数据存储:当你只需要一个简单的类来存储数据,并且不需要额外的行为时,Record 是一个很好的选择。例如,用于表示数据库查询结果、配置参数等。
  • 不可变数据:如果你需要确保数据的不可变性,Record 是理想的,因为它的字段是 final 的,并且没有提供修改字段的方法。

与其他特性的结合

  • 与 Stream API 结合:Record 可以很好地与 Stream API 结合使用。例如,可以使用 Stream 对 Person Record 对象的集合进行过滤、映射和归约操作:
import java.util.List;
import java.util.stream.Collectors;

public class RecordWithStream {
    public static void main(String[] args) {
        List<Person> people = List.of(
                new Person("Alice", 30),
                new Person("Bob", 25),
                new Person("Charlie", 35)
        );

        List<String> names = people.stream()
               .filter(person -> person.age() > 28)
               .map(Person::name)
               .collect(Collectors.toList());

        System.out.println(names);
    }
}
  • 与 Lombok 结合:如果你仍然在使用 Lombok,可以将 Record 与 Lombok 结合使用,进一步简化代码。例如,Lombok 的 @Value 注解与 Record 有相似的功能,但 Record 是 Java 语言的原生特性。

小结

Java Record Type 是一个强大的特性,它简化了不可变数据类的创建,减少了样板代码,提高了代码的可读性和可维护性。通过了解 Record 的基础概念、使用方法、常见实践和最佳实践,开发者可以更加高效地使用这一特性,编写更加简洁、优雅的 Java 代码。

参考资料