Hello! Two samples:
record Test(int[] args) { public Test(int... args) { this.args = args; } } and record Test(int... args) { public Test(int[] args) { this.args = args; } } Both are accepted by javac (14-ea+27-1339). In both cases, record component varargness is ignored and canonical constructor varargness is taken into account upon record object instantiation. However, I'm not quite sure that this is expected behavior. I feel it would be more logical, were compiler reject such records. It looks like javac behavior aligns with the current spec draft [1]: > The types of the formal parameters in the formal parameter list of the > canonical constructor must be identical to the declared type of the > corresponding record component. Looking into 8.10.1 I see: > If the record component is a variable arity record component, then the > declared type is an array type specified by 10.2. So we can conclude that the record component declared as `int... args` and formal parameter declared as `int[] args` have identical type `int[]`, so no compilation error should occur. Still, this looks too permissive. Once we declare a canonical constructor, record component varargness completely loses its meaning. Also looking into the record header alone, one cannot say whether it's possible to use varargs to construct a record instance, because it's possible that the canonical constructor exists and it overrides the varargness. I feel that the spec should add one more restriction to canonical constructors, e.g.: - If the record component is a variable arity record component, the corresponding canonical constructor formal parameter must be a variable arity parameter and vice versa. What do you think? With best regards, Tagir Valeev [1] http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191125/specs/records-jls.html#jls-8.10.4 P.S. And happy holidays to everybody who has holidays!