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