Reflection on records
Ethan McCue
ethan at mccue.dev
Mon Dec 1 16:53:42 UTC 2025
Here is a thread from ~ a year ago which hit some similar notes
https://mail.openjdk.org/pipermail/amber-dev/2024-December/009121.html
On Mon, Dec 1, 2025 at 11:51 AM David Alayachew <davidalayachew at gmail.com>
wrote:
> Thank you Artyom.
>
> This mailing list is actually my final stop. I already asked in multiple
> other places.
>
> And thanks for the suggestions about MethodHandles and InvokeDynamic. I
> think that might be overkill, so I'll probably just abandon the idea for
> now.
>
> Either way, I sent a new message on the mailing list, asking for a new
> feature for records. All of the suggestions I've received thus far feel
> like trying to fit 10 pounds of dirt in a 5 pound bag. It feels like the
> language/compiler could step in and provide us with better tools.
>
>
> On Mon, Dec 1, 2025, 9:57 AM Artyom Drozdov <artyomcool2 at gmail.com> wrote:
>
>> Hello David,
>>
>> If you absolute sure that you need that, it is possible to extract method
>> name and signature from method reference (and access via MethodHandle or
>> Reflections later) by analyzing class file and InvokeDynamic instruction
>> (you probably will need some time to learn how it works if you are not
>> familiar yet).
>>
>> Personally, I'd prefer annotations + reflections + method handle approach
>> (or drop the idea at all).
>>
>> I also think that resources like StackOverflow might suit your goal
>> better than amber-dev mailing list)
>>
>> Regards,
>> Artyom Drozdov
>>
>> пн, 1 дек. 2025 г., 15:47 David Alayachew <davidalayachew at gmail.com>:
>>
>>> Understood. Thanks @Stephen Colebourne <scolebourne at joda.org>.
>>>
>>> And yes @Attila Kelemen <attila.kelemen85 at gmail.com>, I agree that it
>>> being an annotation does make it less ideal. Plus, I lose out on other
>>> things that the compiler might one day give us, like exhaustiveness
>>> checking. All in all, it is still the best solution, but not one I am a fan
>>> of.
>>>
>>>
>>> On Mon, Dec 1, 2025, 4:55 AM Attila Kelemen <attila.kelemen85 at gmail.com>
>>> wrote:
>>>
>>>> There are some other downsides as well: You will have to force your
>>>> clients to specifically design their records to your API (i.e., annotate
>>>> it, and configure the annotation processor). Though, in your case that is
>>>> probably not too bad, because likely they want to design their DTO for your
>>>> API anyway. The other downside is that you will have to write the IDE
>>>> support as well (e.g., Idea's editor will have red curlys around without
>>>> it). Which, aside from the additional maintenance cost, can be a problem
>>>> for a user who is not allowed to install arbitrary IDE plugins. Also,
>>>> compared to the original outline, you probably want an additional generic
>>>> argument for the record type on `RecordComponentWrapper` for type safety.
>>>>
>>>> David Alayachew <davidalayachew at gmail.com> ezt írta (időpont: 2025.
>>>> dec. 1., H, 1:53):
>>>>
>>>>> Thanks Stephen.
>>>>>
>>>>> Hmmmmm, so this is definitely the best solution I have seen thus far.
>>>>> The only real downside is that the static final field has a different name
>>>>> than the actual record component. But I can probably fix that by making it
>>>>> an inner class or something, as opposed to sharing the same namespace as
>>>>> the record itself.
>>>>>
>>>>> Can you link me to the annotation code?
>>>>>
>>>>> On Sun, Nov 30, 2025 at 4:05 PM Stephen Colebourne <
>>>>> scolebourne at joda.org> wrote:
>>>>>
>>>>>> There is a way to do this, but it isn't pretty. Use annotation
>>>>>> processing.
>>>>>>
>>>>>> @GeneratedRecordComponentInterface
>>>>>> record User(String firstName, String lastName, ComplexObject
>>>>>> complexColumn) implements UserColumns {}
>>>>>>
>>>>>> // annotation processor generates:
>>>>>> public interface UserColumns {
>>>>>> public static final RecordComponentWrapper<String>
>>>>>> FIRST_NAME_COMPONENT = new RecordComponentWrapper(User.class,
>>>>>> "firstName");
>>>>>> public static final RecordComponentWrapper<String>
>>>>>> LAST_NAME_COMPONENT = new RecordComponentWrapper(User.class,
>>>>>> "lastName");
>>>>>> public static final RecordComponentWrapper<ComplexObject>
>>>>>> COMPLEX_COLUMN_COMPONENT = new RecordComponentWrapper(User.class,
>>>>>> "complexColumn");
>>>>>> }
>>>>>>
>>>>>> where `RecordComponentWrapper` is some suitable type-safe wrapper for
>>>>>> record components.
>>>>>>
>>>>>> Although there is a string for each record component, it is in
>>>>>> generated code, thus won't get out of sync.
>>>>>>
>>>>>> (This is the annotation processing equivalent to how Joda-Beans
>>>>>> meta-properties have worked for many years)
>>>>>> Stephen
>>>>>>
>>>>>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20251201/0d8a7df1/attachment.htm>
More information about the amber-dev
mailing list