RFR: JEP 359-Records: reflection code
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Tue Oct 22 10:01:47 UTC 2019
Thinking more,
I think the fundamental reason as to why the bootstrap method leaves me
not 100% convinced is that, on the one hand, ObjectMethods tries hard to
be a _general_ helper class, offering a bootstrap method to compute
equals/hashCode/toString on _all_ classes, not just records. And, I
think, it is because of that generality that the bootstrap method
receives a bunch of getter method handles - so that e.g. other language
implementation can still use these methods on regular POJOs.
But, if this is meant to be a general building block, then I don't
understand e.g. why we are unifying all the signatures. If a client
wants hashCode, I think it is kind of a design flaw that (i) there's no
such BSM with that name (the BSM is just called "bootstrap") and (ii)
that there still a requirement to pass a 'name list', which is ignored
by the BSM.
So, the _general_ building block case seems to push for one BSM per
Object method, whereas the record translation use case seems to push
towards a single unified BSM.
I think we can actually have our cake and eat it too:
1) ObjectMethods could expose several BSMs - one for each Object method,
with the _right_ static argument list and names, to make it easy for
clients to find them. Of course, for generality, these methods should be
expressed in terms of MethodHandle[], since we can't rely on the class
being a record
2) We coud add a j.l.Record.bootstrap, which, using core reflection
could extract the required ingredients, before delegating to the _right_
BSM in ObjectMethods (e.g. the MH list and the names list)
This way we get the best of both worlds: sharp BSMs for clients that
just want to implement object methods (which also works on things that
are not records); unified BSM which act as a record translation target.
Maurizio
On 22/10/2019 10:41, Chris Hegarty wrote:
>
>
>> On 22 Oct 2019, at 09:51, Maurizio Cimadamore
>> <maurizio.cimadamore at oracle.com
>> <mailto:maurizio.cimadamore at oracle.com>> wrote:
>>
>> ..
>>
>> Let me rephrase. We have Class::getRecordComponents; and we have
>> RecordComponent::accessor.
>>
>> What is the need to pass _anything_ to the BSM, other than the record
>> class (e.g. Point.class) AND the method name (e.g. toString) ?
>>
>> The BSM can take the .class, and get the components; from there:
>>
>> - you can easily derive names
>> - you can also easily derive accessor MHs (just a lookup away)
>>
>> I was _not_ advocating for extracting a name from a direct method
>> handle - that seems brittle, given that the compiler implementation
>> might change, eventually. But doubling down on the reflection API
>> seems the right thing to do?
>
> A quick change shows that this simplifies the code a lot ( since there
> is less arg checking )
>
> http://cr.openjdk.java.net/~chegar/records/ObjectMethods.00/
>
> Q: the TypeDescriptor arg can be used for linking a dynamic constant.
> Is this still needed?
>
> -Chris.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20191022/011bf3f0/attachment.html>
More information about the compiler-dev
mailing list