On 10/12/2020 14:11, fo...@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


Reply via email to