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

Reply via email to