Should final fields in records be trusted or not trusted in 16?
John Rose
john.r.rose at oracle.com
Thu Dec 10 19:46:02 UTC 2020
On Dec 10, 2020, at 6:35 AM, Chris Hegarty <chris.hegarty at oracle.com> wrote:
>
>
>> On 10 Dec 2020, at 14:11, forax at univ-mlv.fr <mailto:forax at univ-mlv.fr> wrote:
>>> ...
>>
>> There is a third choice see above.
>>
>> Forcing the semantics of Java into the VM is always a bad idea.
>> We don't do that for any other constructs, lambda, enums, Java anonymous classes, etc.
>> Worst, we already know that an inline record is not a record from the JLS POV.
>>
>> For Java 16, given that we are late in the process, i see no problem if the VM doesn't trust record fields as a temporary patch, if it's easier than to have Field.set() to ask if a class is a plain class or not. It's far better than having the the JLS definition of a record bolted into the VM.
>
> In my view, this is an “everyone loses” option.
+100 The question is, must everyone lose this battle? I hope not.
I am content, for the present, with a “hacky” rule that says,
as narrowly and restrictively as necessary, “if it’s a JLS record,
then the JVM defends the fields, period”.
The hackiness can be lifted over time after we (hello Mandy!)
figure out how to make final fields more uniformly trustable.
We don’t have a complete solution yet, but that does not
mandate protecting fields we know can merit special
protection. Current examples of fields that enjoy special
protection:
- static finals (true forever)
- fields of certain “locked down” JDK classes (HotSpot ad hoc logic)
- hidden classes (new feature, new behavior)
- records (assuming non-rollback of JDK-8247444)
Perhaps the more important defining feature of records is the
restricted process by which instance are created: Via a canonical
constructor. This is important to defend, even apart from the
integrity of final fields. And this leads me to what I think is the
most compelling reason for making a “special pleading” for
record fields (i.e., JDK-8247444): If we don’t defend record fields
against reflective Field.set, we will open the gate for off-label
creation of records *apart from the canonical constructor*.
This subverts, not only a desirable set of optimizations on
records, but also a crucial invariant, that every record comes
from a CC invocation. Let’s not allow that; indeed that would
be another aspect of “everybody loses”.
> If we do not prevent Field.set() from modifying the fields of a record
> class in Java 16, then it will be almost impossible to do so at some
> future point. The intermediate step that we’re proposing both allows
> for 1) TNSFF in record classes, and 2) an evolution path to a more
> general mechanism in the future. I do not see that no.1 is covered by
> option three.
Yes. I think given the life-cycle restrictions on records, even if
our future more general evolution path for finals is *inconsistent*
with what we did in JDK-8247444, we still win, because records
have a special property. Let’s not dilute that property (having
invested so much in records!), even if there is a risk that what
we did in JDK-8247444 will be inconsistent with the future
general facility. But (spoiler alert) I’m sure it won’t be; I’ve
been watching this technology arc in the JVM for a long time,
and I think JDK-8247444 is not a side-trip, but squarely along
the center-line of what we want to do long term.
— John
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20201210/6aa36182/attachment.htm>
More information about the amber-spec-experts
mailing list