Feature Request -- Enumerate the RecordComponents of a record
Attila Kelemen
attila.kelemen85 at gmail.com
Mon Dec 1 18:10:10 UTC 2025
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/5e963d61/attachment.htm>
More information about the amber-dev
mailing list