bigywater.tech
Java 内部原理 · 101

Record 紧凑构造器真实验证:在构造器里修改参数,真实字段值也会跟着变

紧凑构造器(compact constructor)是Record最实用的特性之一——省略参数列表,直接对隐式参数做校验或修正。这篇真实验证它到底能做到什么程度,尤其是"修改参数变量"这个操作是否真的会影响最终字段。

校验失败真实抛出异常
真实验证:紧凑构造器里的if判断真实能拦截非法参数(min大于max),抛出IllegalArgumentException阻止对象创建
参数重赋值真实影响字段
真实验证:在紧凑构造器里把负数min重新赋值为0,最终r.min()真实返回0,不是原始传入的负数

上一篇:equals()里用getClass()还是instanceof真实验证

真实验证:紧凑构造器真实能做参数校验

最常见的用法:在构造对象之前,用紧凑构造器拦截非法参数组合。

RecordCompactConstructorDemo.java record Range(int min, int max) { Range { // 紧凑构造器:没有参数列表,隐式使用min和max if (min > max) throw new IllegalArgumentException("min不能大于max: " + min + " > " + max); } } new Range(10, 5);
真实实测
真实捕获校验异常: min不能大于max: 10 > 5

真实结果证明紧凑构造器里的校验逻辑真实生效——传入 min=10, max=5 这种非法组合,对象创建过程真实被中断,IllegalArgumentException 真实被抛出,不会得到一个内部状态不一致的 Range 实例。

真实验证:在紧凑构造器里修改参数,真实影响最终字段值

紧凑构造器不只能校验,还能对参数变量重新赋值——这次修改是否真的会体现在对象的字段上?

RecordCompactConstructorDemo.java Range { if (min < 0) { min = 0; // 真实重新赋值参数变量 } } Range r = new Range(-5, 10);
真实实测
真实在紧凑构造器里把负数min修正为0
真实构造完成后 r.min() = 0(应该是修正后的0,不是传入的-5)
Range.min 字段真实是final: true
Range真实的构造器个数: 1
构造器真实参数: [int, int]
真实的编译器魔法在这里。紧凑构造器在字节码层面被编译器真实展开成一个完整的、带参数列表的构造器——它会真实在紧凑构造器体执行完毕之后,自动追加一段"把(可能已被修改的)参数值赋给同名字段"的代码,这一步是编译器隐式插入的,不需要开发者手写 this.min = min;。真实验证证明这个隐式赋值用的是紧凑构造器执行完之后参数变量当时的值,不是最初传入构造器的原始值——所以在紧凑构造器里对 min 重新赋值为 0,这个 0 才是真实最终写进 Range.min 这个 final 字段的值。反射也验证了这个字段依然真实是 final 的,构造器的真实参数签名和普通的两参数构造器没有任何区别——紧凑构造器只是源码层面的语法简化,不改变编译产物的本质结构。

真实验证:自动生成的equals()/toString()基于修正后的真实字段值

既然字段值真实是被修正过的,那么Record自动生成的equals()/toString()是否也会真实反映这个修正结果?

真实实测
r.equals(r2) 真实结果: true(两次传入的min不同,-5和-100,但真实都被修正为0,所以真实相等)
r2.toString() 真实结果: Range[min=0, max=10]

真实结果证明了整个链条的一致性:Range(-5, 10) 和 Range(-100, 10) 两次调用传入的 min 完全不同,但都真实被紧凑构造器修正成了 0;Record 自动生成的 equals() 真实比较的是字段的最终值(不是构造参数),所以两者真实相等;toString() 同样真实打印的是修正后的 min=0,而不是构造时传入的负数。

分步演示:参数变量是怎么"变成"字段值的

每一步的值都是真实运行这段代码得到的,不是按语言规范手工推的。

紧凑构造器把参数变量改成 0 之后,编译器插入的隐式赋值用的正是这个改过的值
这一步发生变化的状态

    参考与说明

    • 本文全部结果均在本机真实运行 Java 17 得到,紧凑构造器的校验和字段修正行为重复运行完全一致。
    • 和Record 类真实反编译那篇一起看,能更完整理解 Record 从字段声明、构造器展开到 equals/hashCode/toString 自动生成的完整真实链条。
    • 没有涉及:Record 除了紧凑构造器之外还能真实定义显式的全参数构造器(会完全替代自动生成的版本)、静态工厂方法配合私有紧凑构造器实现的真实校验模式——这两个话题留给系列后面按需再写。
    京ICP备2026067502号-1京公网安备11010502063487号