JDK 21 中 Record 的用法详解(附完整示例)

📌 前言

record 是 Java 16 正式引入的新语法,用来编写轻量级、只包含数据的不可变类。
到了 JDK 21,record 已经非常成熟,并且配合模式匹配(Pattern Matching)可以写出更简洁的代码。

本文将从基础语法、构造器、方法、自定义校验到 JDK21 新特性全方位讲解 record 的使用方式。


📘 目录

  1. 什么是 Record?

  2. Record 的基本使用

  3. 自动生成的内容

  4. Record 的构造器用法

  5. Record 中定义方法

  6. 允许和不允许的内容

  7. 深不可变处理方式

  8. Record 与 sealed 配合(JDK21)

  9. Record 模式匹配(JDK21)

  10. 总结


1. 什么是 Record?

record 用来创建 不可变数据类(data carrier class)

它会自动帮你生成:

  • private final 字段

  • 构造器

  • equals()

  • hashCode()

  • toString()

  • getter(无前缀,方法名就是字段名)


2. Record 的基本使用

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

使用方式:

User u = new User("Alice", 20);
System.out.println(u.name()); // Alice
System.out.println(u.age());  // 20

3. 自动生成的内容

假设你写了:

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

Java 会自动生成等价于:

private final String name;
private final int age;

public User(String name, int age) { ... }

public String name() { return name; }
public int age() { return age; }

public boolean equals(Object o) { ... }
public int hashCode() { ... }
public String toString() { ... }

你完全不需要自己写!


4. Record 的构造器用法

🔸(1)规范构造器(Canonical Constructor)

你可以给 record 添加校验逻辑:

public record User(String name, int age) {
    public User {
        if (age < 0) {
            throw new IllegalArgumentException("age must be >= 0");
        }
    }
}

这是最常用的方式。


🔸(2)额外构造器(Overloaded Constructor)

public record Point(int x, int y) {
    public Point(int value) {
        this(value, value);
    }
}

5. 在 Record 中定义方法

record 和普通类一样可以添加方法:

public record User(String name, int age) {
    public String info() {
        return name + " (" + age + ")";
    }
}

6. Record 中允许与不允许的内容

✔ 允许的内容

  • 定义方法

  • 定义静态字段、静态方法

  • 实现接口

  • 重写构造器

  • 使用注解

❌ 不允许的内容

  • 不能继承其他类(但可以实现接口)

  • 不能定义可变字段(如 int x;

  • 不能定义 setter

例如:

public record User(String name) {
    private int age; // ❌ 编译错误
}

7. Record 是否真的不可变?(深浅不可变问题)

record 提供的是浅不可变:字段本身是 final,但字段内部对象可以变。

例子:

public record Order(String id, List<String> items) { }

Order o = new Order("1", new ArrayList<>(List.of("A", "B")));
o.items().add("C"); // ❗Allowed(内部 List 可以变)

如果你需要深不可变,可以在构造器里拷贝:

public record Order(String id, List<String> items) {
    public Order {
        items = List.copyOf(items);
    }
}

8. Record 搭配 sealed(JDK21 完整支持)

在 JDK21 中,你可以把 record 放进 sealed 层级结构:

public sealed interface Shape permits Circle, Rectangle { }

public record Circle(double r) implements Shape { }
public record Rectangle(double w, double h) implements Shape { }

这让 record 特别适合建模领域对象(DDD)。


9. Record 模式匹配(Pattern Matching)→ JDK21 新特性

从 JDK 21 开始,switch 可以直接解构 record:

record Point(int x, int y) {}

static String format(Object o) {
    return switch (o) {
        case Point(int x, int y) -> "Point: " + x + "," + y;
        default -> "Unknown";
    };
}

这让 record 使用起来更像 Kotlin 的 data class。


10. 总结

能力是否支持
自动生成构造器、equals、hashCode、toString
字段不可变(final)
深不可变❌(需要自己处理)
实现接口
继承类
自定义构造器
模式匹配(JDK21)

Record 的核心价值:少写大量模板代码,写出更简洁、安全的数据类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值