Reflection on records

Attila Kelemen attila.kelemen85 at gmail.com
Mon Dec 1 09:55:31 UTC 2025


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/4383fa81/attachment.htm>


More information about the amber-dev mailing list