canonical 构造器是编译器为 record 自动生成的、参数顺序/类型/数量严格匹配组件声明的 public 构造器,不可省略或重写;非 canonical 构造器由开发者显式声明,须通过 this(...) 委托调用 canonical 构造器,用于参数转换或简化初始化。

Java record 的 canonical 构造器是编译器自动生成的、与 record 声明中组件列表完全匹配的那个构造器;非 canonical 构造器则是开发者显式声明的其他构造器,用于提供额外的初始化方式或参数转换逻辑。
canonical 构造器是什么
当你定义一个 record,比如 record Person(String name, int age) {},编译器会自动为你生成一个 public 的构造器:Person(String name, int age)。这个构造器就是 canonical 构造器——它参数顺序、类型、数量严格对应 record 的组件声明,且默认执行字段赋值(即把参数直接赋给对应组件)。
它不可省略,也不能被重写(不能用 public Person(...) 再声明一次同签名的构造器),否则编译报错。
如何声明非 canonical 构造器
你可以在 record 中显式添加其他构造器,只要签名不同于 canonical 构造器即可。这些构造器必须委托调用 canonical 构造器(通过 this(...)),不能直接初始化组件字段。
- 允许:接受不同参数(如
String fullName),内部解析后调用this(name, age) - 允许:带默认值逻辑,比如
Person(String name) { this(name, 0); } - 禁止:绕过
this(...)直接写this.name = name;(record 组件是 final 且私有,不可直接赋值)
非 canonical 构造器的典型用途
它们主要用来提升 API 可用性,而不是改变 record 的不可变语义。
-
参数预处理:例如传入 ISO 格式字符串,构造器解析为
LocalDate后再委托给 canonical 构造器 -
兼容旧接口:比如已有系统传入
Map<string object></string>,可新增构造器从中提取字段 - 简化调用:对可选字段提供零参或单参构造器,内部填默认值
注意点与限制
record 的设计目标是透明、不可变、数据驱动,因此构造器机制也受约束:
- 所有构造器(包括非 canonical)最终都必须通过
this(...)调用 canonical 构造器一次,且只能在第一行 - 不能声明实例初始化块(
{ ... })或实例字段 - 如果 record 包含泛型参数,canonical 构造器的类型参数会自动推导,非 canonical 构造器需显式保持一致
- 反射获取构造器时,canonical 构造器的
getParameters()顺序和 record 组件声明严格一致,这是其“规范性”的体现
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











