Hello! Reading the latest JLS spec draft for records, chapter 8.10.4 [1] I see the following:
For a record type R, the canonical constructor is a public constructor whose formal parameter list is identical to the record component list of R, with no throws clause. If the canonical constructor is explicitly declared, then it must satisfy the following; otherwise a compile-time error occurs: - The body of the canonical constructor must not contain a return statement (14.17). - Every field corresponding to a record component of R must be definitely assigned and moreover not definitely unassigned (16.9) at the end of the body of the canonical constructor. - All the other rules for a constructor in a normal class declaration must be satisfied (8.8). Several points are unclear to me 1. It's not explicitly specified whether an explicitly declared canonical constructor must be 'public' like it's specified for compact constructors. Does this mean that I can declare non-public canonical constructor? 2. I see the restriction for not having a return statement quite arbitrary. I understand it for compact constructors but see no reason for this restriction in non-compact canonical constructors. Could anybody provide a rationale behind this restriction? Sorry if it was discussed; in this case, links to the discussion would also be appreciated. 3. As it's already mentioned in 8.10.3, each record component implies an implicitly declared private final field. And as 8.3.1.2 [2] says, "A blank final instance variable must be definitely assigned and moreover not definitely unassigned at the end of every constructor of the class in which it is declared". Thus "Every field corresponding to a record component of R must be definitely assigned and moreover not definitely unassigned..." part seems redundant as it's covered by normal constructor rules. Probably it's not harmful to specify this explicitly though. 4. While this can be deduced from other parts of the spec I would explicitly add that an explicit constructor invocation statement (8.8.7.1) is disallowed in canonical constructor (including the compact form). E.g.: If the canonical constructor is explicitly declared, then it must satisfy the following; otherwise a compile-time error occurs: - The body of the canonical constructor must not contain an explicit constructor invocation statement (§8.8.7.1). ... Note that 8.9.2 (enum body declaration) contains the similar statement: It is a compile-time error if a constructor declaration in an enum declaration contains a superclass constructor invocation statement (§8.8.7.1). With best regards, Tagir Valeev. [1] http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html#jls-8.10.4 [2] https://docs.oracle.com/javase/specs/jls/se13/html/jls-8.html#jls-8.3.1.2