RFR: JDK-8282798 java.lang.runtime.Carrier

Remi Forax forax at univ-mlv.fr
Tue Mar 8 17:28:13 UTC 2022


----- Original Message -----
> From: "John R Rose" <jrose at openjdk.java.net>
> To: "core-libs-dev" <core-libs-dev at openjdk.java.net>
> Sent: Tuesday, March 8, 2022 5:55:00 PM
> Subject: Re: RFR: JDK-8282798 java.lang.runtime.Carrier

> On Tue, 8 Mar 2022 15:59:59 GMT, Maurizio Cimadamore <mcimadamore at openjdk.org>
> wrote:
> 
>>> We propose to provide a runtime anonymous carrier class object generator;
>>> java.lang.runtime.Carrier. This generator class is designed to share anonymous
>>> classes when shapes are similar. For example, if several clients require
>>> objects containing two integer fields, then Carrier will ensure that each
>>> client generates carrier objects using the same underlying anonymous class.
>>> 
>>> See JBS for details.
>>
>> src/java.base/share/classes/java/lang/runtime/Carrier.java line 48:
>> 
>>> 46:
>>> 47: /**
>>> 48:  * This  class is used to create objects that have number and types of
>> 
>> The class javadoc seems a bit on the thin side. I would say something on the
>> fact that the shape of the carrier is determined by a MethodType, etc, and add
>> an example to illustrate basic usage.
> 
> Agreed.  Also, this class is unusual in that it is not instantiated; like
> `Arrays` or `Collections` it is a (small) bundle of static factories (or are
> they algorithms?).  I think as such it should be called `Carriers`.
> 
> I'm slightly surprised the MH factories are not factored through a metaobject of
> the form
> 
> record CarrierBinding(
>    MethodType methodType,
>    MethodHandle constructor,
>    List<Class<?>> componentTypes,
>    List<MethodHandle> components)
> { … }

Yes, i've done something very similar
https://github.com/forax/switch-carrier/blob/master/src/main/java/com/github/forax/carrier/java/lang/runtime/Patterns.java#L172

Note that constructor.type() == methodType and constructor.parameterList() == componenetTypes,
so the record can be reduced to a tuple (constructor / components).

> 
> 
> The presupposition here, I suppose, is that carriers will only be used by condy
> or similar quasi-statically configured clients, so having the multiple lookups
> through a hidden table is no burden, and the clients can always keep the
> associations correct (between constructors and various component accessors).
> 
> **But** if I were to use carriers to manage intermediate structures in (say) a
> serialization package (for instance) I would need to make my own records like
> the above for my own bookkeeping, and I would be slightly miffed that the
> Carrier API insisted on doing a de-novo lookup twice on each MT key (to say
> nothing of me having to create the MT key first).

It depends if you want to use the same carrier for several cases or not.

> 
> **And** if I were to use carriers in that way (away from condy), **then** I
> would want to skip the step of building the MethodType, and wish for a factory
> method for CarrierBinding instances that took a plain List<Class>, as well as a
> factory method that took the MethodType (which is convenient for condy).

As i said above, constructor.type() == methodType so anyway the MethodType has to be created.

> 
> BTW, it would be normal to give the name `Carrier` (which is a good name BTW) to
> the record type that embodies the group of method handles, so `record
> Carrier(…constructor…components…) {…factories…}`.
> 
> I suppose stuff like this could be added later.  But it's worth considering now,
> simply because there is an early decision point between a class named `Carrier`
> and a static-only class named `Carriers`.

Rémi



More information about the core-libs-dev mailing list