📌 前言
record 是 Java 16 正式引入的新语法,用来编写轻量级、只包含数据的不可变类。
到了 JDK 21,record 已经非常成熟,并且配合模式匹配(Pattern Matching)可以写出更简洁的代码。
本文将从基础语法、构造器、方法、自定义校验到 JDK21 新特性全方位讲解 record 的使用方式。
📘 目录
-
什么是 Record?
-
Record 的基本使用
-
自动生成的内容
-
Record 的构造器用法
-
Record 中定义方法
-
允许和不允许的内容
-
深不可变处理方式
-
Record 与 sealed 配合(JDK21)
-
Record 模式匹配(JDK21)
-
总结
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 的核心价值:少写大量模板代码,写出更简洁、安全的数据类。
391

被折叠的 条评论
为什么被折叠?



