Updated Draft specs for JEP 359 (Records)
Florian Weimer
fw at deneb.enyo.de
Sat Nov 2 13:34:30 UTC 2019
* Brian Goetz:
>> Is it allowed to declare a canonical constructor explicitly and make
>> it non-public? I think the naswer is no. But it's not quite obvious
>> from the spec, I think.
>
> No, it is not.
>
> The basic idea is that with a record, you’ve given up the right to
> decouple your API from the representation, which is declared in the
> header. So you will get a public canonical constructor, accessors,
> state-based Object methods, and eventually, a deconstruction pattern.
> You can “override” these methods, but subject to an invariant:
> “copying” a record (feeding the result of its accessors to its
> canonical actor) must be equals() to the original. A record is the
> state, the whole state, and nothing but the state.
Sorry, I don't think the current specification of explicitly declared
canonical constructors achieves this. As far as I can tell, this is
legal:
record R(int i) {
public R(int i) {
this.i = i + 1;
}
}
It also means that serialization with constructor invocation will not
produce something that compares equal to the original record.
What is the use case for transformation of record fields in canonical
constructors? I would expect canonical constructors to have an
implicit preamble which assigns all the fields, similar to the compact
form. All these constructors can do is checking that the record
invariants aren't violated.
There is definitely a tension here between encapsulation (of how the
internal state is constructed) and transparent construction of record
values (for the purposes of serialization, but there could be other
applications as well).
(If this has already been discussed to death, I will shut up. I
understand I'm very late to the party. Sorry.)
More information about the amber-dev
mailing list