Feature Request -- Enumerate the RecordComponents of a record
David Alayachew
davidalayachew at gmail.com
Mon Dec 1 20:15:54 UTC 2025
Thanks for the response @Attila Kelemen <attila.kelemen85 at gmail.com>.
Yes, I am definitely not married to the concept of using an enum or an
inner class. There are clear flaws with it, and I only use it to explain
what I really want.
Really, all I want is to be able to enumerate the components of a record
and also get exhaustiveness checking.
As for your implementation suggestion, no real comments. As long as it
works, I am fine with any implementation.
On Mon, Dec 1, 2025, 1:10 PM Attila Kelemen <attila.kelemen85 at gmail.com>
wrote:
> Hi,
>
> My concern with the actual proposal (not with the problem it is trying to
> solve) is that it doesn't generalize well. That is, imagine if function
> types get added to the language with support to query the parameters, etc.
> of the underlying function. Then immediately this change becomes a useless
> (in fact, harmful) noise.
>
> So, let me give a counter proposal (even though I'm quite certain it will
> not be added anytime soon given all the important stuff in the queue):
>
> Allow the following construct:
>
> ```
> RecordComponentAccessor accessor = MyRecord::myComponent;
> ```
>
> where the `RecordComponentAccessor` could look like it (of course, doesn't
> have to be an interface):
>
> ```
> interface RecordComponentAccessor<R, V> {
> Type recordType();
> Class<? extends R> recordRawType();
>
> String componentName();
>
> Type componentType();
> Class<?> componentRawType();
>
> MethodHandle getter();
>
> default V getValue(R record) {
> // TODO: Deal with `throws Throwable`
> return getter().invoke(record);
> }
> }
> ```
>
> The benefit of this is that, if function types ever become a thing, then
> of course this can be retrofitted to implement (or extend) the function
> type `(R) -> V` (or whatever notation it would have), which would likely
> have more generic methods like `List<Class<?>> parameterRawTypes()`, etc.
>
> In my opinion, this is not harder to implement than the original proposal,
> and more future proof. And if it is only implemented for records, then no
> massive changes to the JVM needed (unlike with the introduction of a full
> blown function type).
>
> Attila
>
> David Alayachew <davidalayachew at gmail.com> ezt írta (időpont: 2025. nov.
> 30., V, 22:51):
>
>> Hello @amber-dev <amber-dev at openjdk.org>,
>>
>> (this is a follow-up from the previous thread --
>> https://mail.openjdk.org/pipermail/amber-dev/2025-November/009472.html)
>>
>> Since records are *transparent* carriers of data, then that means that
>> all of the record components are known at compile time and visible to all
>> consumers who can reach the record itself.
>>
>> Right now, the only way to reach these record components is by drilling
>> down via j.l.Class ---> j.l.r.RecordComponent. And even then, you are
>> forced into doing String comparison against what you *expect* the record
>> component to be named. That means that you will get a runtime error, not a
>> compile time error, if a record component changes names.
>>
>> I propose that we enumerate the Record Components of a record.
>>
>> My naive way of accomplishing this would be to literally provide each
>> record with its own inner enum, each value corresponding to the respective
>> record component on a record.
>>
>> Consider the following record.
>>
>> record User(String firstName, String lastName, int age) {}
>>
>> I ask that record get access to its own inner enum (let's call it
>> VALUES), that can be referenced. Like this.
>>
>> record User(String firstName, String lastName, int age)
>> {
>> enum Values {
>> firstName,
>> lastName,
>> age,
>> ;
>> public final java.lang.reflect.RecordComponent recordComponent =
>> Arrays
>> .stream(User.class.getRecordComponents())
>> .filter(rc -> rc.getName().equals(this.name()))
>> .findAny()
>> .orElseThrow()
>> ;
>> }
>> }
>>
>> This is better than the current situation for all sorts of reasons.
>>
>> 1. Currently, if I want a RecordComponent, I must make a
>> String-comparison. I lose compile time safety of checking if my hard-coded
>> string no longer matches because someone changed the record.
>> 2. I now get exhaustiveness checking, which really should have been
>> there from the beginning.
>>
>> And of course, I am not tied to the idea of using an enum or an inner
>> class. My real goal is to be able to enumerate over the components of a
>> record. Not even necessarily over the j.l.r.RecordComponents of a record.
>> Whatever form that takes is fine with me.
>>
>> But not being able to enumerate over a records components (obviously, in
>> a type-safe, non-*stringly*-typed way) is making records less powerful
>> for seemingly no reason. The contract and spec enables it, it's just not
>> being utilized.
>>
>> Thank you for your time and consideration.
>> David Alayachew
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20251201/408efe54/attachment.htm>
More information about the amber-dev
mailing list