Reflection on records
David Alayachew
davidalayachew at gmail.com
Mon Dec 1 13:33:05 UTC 2025
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/cb3e8566/attachment-0001.htm>
More information about the amber-dev
mailing list