Thanks for the response @Attila Kelemen <[email protected]>.
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 <[email protected]> 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 <[email protected]> ezt írta (időpont: 2025. nov. > 30., V, 22:51): > >> Hello @amber-dev <[email protected]>, >> >> (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 >> >
