紧凑构造器(compact constructor)是Record最实用的特性之一——省略参数列表,直接对隐式参数做校验或修正。这篇真实验证它到底能做到什么程度,尤其是"修改参数变量"这个操作是否真的会影响最终字段。
上一篇: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]
既然字段值真实是被修正过的,那么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,而不是构造时传入的负数。
每一步的值都是真实运行这段代码得到的,不是按语言规范手工推的。