如何在Java 17中使用记录(record)简化数据类的编写

在Java 14起,record(记录)被引入作为一种特殊的类,用来方便地声明不可变的数据载体。它消除了大量样板代码,使代码更简洁、可读性更好。下面我们从定义、使用、以及与传统POJO的对比等方面,系统介绍record在Java 17中的应用。

1. 记录的基本语法

public record Person(String firstName, String lastName, int age) {}
  • 不可变:字段(Component)默认是 private final,不需要显式写成 final
  • 自动生成:编译器会为你自动生成:
    • 私有 final 字段
    • 构造器(参数对应字段)
    • equals()hashCode()toString() 的实现
    • 访问器方法(如 firstName()lastName()age()
  • 声明简洁:仅需一行代码即可完成。

2. 与传统POJO的对比

特性 传统 POJO Record
字段声明 private + final 直接列出在括号中
构造器 自己写或用 Lombok 自动生成
访问器 getX() x()
equals/hashCode/toString 手写或 Lombok 自动实现
可变性 可变 只读(不可变)

记录适合用于:

  • 传输对象(DTO)
  • 简单数据容器
  • 匿名内部类替代

3. 记录的高级特性

3.1 继承与多态

记录是final类,不能被继承;但是它们可以实现接口。

public interface Identifiable {
    String id();
}

public record User(String id, String name) implements Identifiable {}

3.2 自定义方法与验证

你可以在记录体内添加方法,也可以使用 compact constructor 进行参数验证。

public record Person(String firstName, String lastName, int age) {
    // compact constructor
    Person {
        if (age < 0) {
            throw new IllegalArgumentException("Age cannot be negative");
        }
    }

    public String fullName() {
        return firstName + " " + lastName;
    }
}

3.3 组合与分解

记录的 toString()equals()hashCode() 基于所有字段。若需要排除某些字段,可通过自定义方法实现。

public record SensitiveUser(String username, String password) {
    @Override
    public String toString() {
        return "SensitiveUser{username='" + username + "'}";
    }
}

4. 在Spring Boot中的应用示例

假设我们有一个REST接口,需要返回用户信息。使用Record可以让返回体更简洁。

@RestController
@RequestMapping("/api/users")
public class UserController {

    @GetMapping("/{id}")
    public Person getUser(@PathVariable String id) {
        // 在实际应用中,这里会查询数据库
        return new Person("John", "Doe", 30);
    }
}

Spring Boot 的 Jackson 默认支持序列化/反序列化 Record。

{
  "firstName": "John",
  "lastName": "Doe",
  "age": 30
}

5. 性能与内存

由于 Record 内部使用的是 final 字段,JVM 能够做更多优化。与普通 POJO 相比,内存占用略低,且无可变性导致的线程安全问题。对高并发或数据交换频繁的系统,推荐使用 Record 作为数据传输层。

6. 迁移建议

  • 优先级 1:所有 DTO、VO、DTO-DTO 映射的类可以先尝试改为 Record。
  • 优先级 2:如果业务需要可变字段或特殊序列化逻辑,保留传统类。
  • 注意:记录不能继承,若项目中有继承体系需要慎重。

7. 结语

Java 17 的记录为 Java 开发者提供了一种极简、不可变的数据类实现方式,减少了样板代码,提升了代码可读性和可维护性。掌握 Record 的语法与特性,可以让你在编写现代 Java 应用时更加高效。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注