Should final fields in records be trusted or not trusted in 16?
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Thu Dec 10 15:17:15 UTC 2020
On 10/12/2020 14:11, forax at univ-mlv.fr wrote:
> I disagree, having the VM behaving strictly like Java is a hack. Microsoft has done that with .Net generics which are C# generics. I don't see the point of repeating the errors of the past.
I think you are missing my broader point.
I don't think that waving the "it's always a bad idea to have Java
concepts inside the VM" wand is a trick that can be always applied.
While I generally I agree with you, the case of records does strike me
as different from your typical feature, especially because there's so
much reflection support in there.
* Class:isRecord
* Class:getRecordComponents
There are so many promises implicit in this: for instance, let's look at
getRecordComponents javadoc:
" The components are returned in the same order that they are declared
in the record header. The array is empty if this record class has no
components. If the class is not a record class, that is isRecord()
returns false, then this method returns null. Conversely, if isRecord()
returns true, then this method returns a non-null value."
Ok, so, if "isRecord" is true, then I will get some components out of
this... but when does "isRecord" return true?
"Returns true if and only if this class is a record class. The direct
superclass of a record class is java.lang.Record"||
Now, while this is open to interpretation, my feeling is that "only if
this class is a record class" will be read in a very precise way - the
JLS way, to be explicit.
The isEnum spec is even more explicit and says "Returns true if and only
if this class was declared as an enum in the source code". Now, under
the hood, yes, enums are just classes with a flag, but the Class::isEnum
implementation has an explicit check on the enum supertype. In other
words, the implementation of Class::isEnum and Class::isRecord are 100%
aligned (apart from the fact that one is checking for presence of a flag
and the other is checking for the presence of an attribute). I'd say
this is a pretty strong precedent.
Java reflection has always had a special relationship with Java (the
language). So, IMHO, it's totally fine for methods in core reflection to
refer to JLS properties (such as enum-ness or record-ness) and try to
enforce those in the best way they can.
So, to summarize:
* j.l.Class::isRecord is consistent with j.l.Class::isEnum - so there's
no bug there
* we have other methods in the reflection API (Field::set and
Class::getRecordComponents) which needs some kind of "is record" predicate
* adding two subtly different predicates, and use one or the other
depending on, well, convenience, still seems like an odd solution
Maurizio
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20201210/3bd63344/attachment-0001.htm>
More information about the amber-spec-experts
mailing list