Possible records tweak
John Rose
john.r.rose at oracle.com
Wed Apr 29 18:37:20 UTC 2020
On Apr 29, 2020, at 10:07 AM, Gavin Bierman <gavin.bierman at oracle.com> wrote:
>
> Talking it through with Dan, I think the best thing for the JLS is to avoid issues of `this` etc and simply state:
>
> It is a compile-time error to assign to the instance fields of the record class in the body of the compact constructor.
>
> Thoughts?
That sounds fine to me. There was at least one reason to be more
restrictive, and that was to help users avoid accidentally observing
non-initialized fields.
So I’ve lost track of this bit: What happens if the compact constructor
calls a virtual method on this? (Say it doesn’t explicitly mention ’this’.)
What are the states of the fields when the virtual method runs before
and after variable assignments in the compact constructor? All default?
Some default some not? To really rub it in:
class RecordFieldChangeExperiment {
record R0(int x) {
public R0 {
observeField();
}
void observeField() {
System.out.println(x);
}
}
record R1(int x) {
public R1 {
observeField();
++x; // could be x = Math.max(x, 0);
//WAS: this.x = x+1; // could be this.x = Math.max(x, 0);
observeField();
}
void observeField() {
System.out.println(x);
}
}
record R2(int x) {
public R2 {
observeField();
++x; // could be x = Math.max(x, 0);
observeField();
++x; // could be x = Math.min(x, 1000);
observeField();
}
void observeField() {
System.out.println(x);
}
}
public static void main(String... av) {
new R0(100).observeField();
// 100 100 NO?
// 0 100 YES?
new R1(100).observeField();
// 100 101 101 NO?
// 0 101 101 NO?
// 0 0 101 YES?
new R2(100).observeField();
// 100 101 102 102 NO?
// 0 0 102 102 NO?
// 0 0 0 102 YES?
}
}
I think the principled answer is to specify that fields have
their default values until after the primary constructor exits.
This will surprise people who expect to read the fields in
virtual methods called from the constructor. Having all
the fields always in their default values is, at least, predictable.
IMO that makes up for the surprise, because it can be learned.
The other compromises (especially making fields mutable
multiple times) lead to more variable behaviors, ensuring
a long train of future surprises.
(And do any of these observations apply to non-compact
constructors? I suppose the answer is “whatever rules apply
to non-record classes also apply to records with non-compact
canonical constructors”.)
— John
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20200429/2acfb087/attachment-0001.htm>
More information about the amber-spec-experts
mailing list