Reflection on records
Kirill Semyonkin
burnytc at gmail.com
Sun Nov 30 20:04:15 UTC 2025
Hello David,
I've seen some people (ab)use Serializable and SerializedLambda to get
names of the class and the method, with numerous examples like
https://stackoverflow.com/a/53397378/16208077. From there you can traverse
usual reflection with those strings to get the exact RecordComponent or
some other reflection object. But those strings come from users doing
method references, so you will get the behavior that you wanted, at least
to some extent. Although it slightly feels like an XY problem.
- Kirill Semyonkin
вс, 30 нояб. 2025 г. в 22:57, Attila Kelemen <attila.kelemen85 at gmail.com>:
> I guess, if your record type is fixed, then you can have a dummy instance
> of that record with all fields being different (hopefully, no 3 boolean
> components :)), and then you can do the same hack as with the interface +
> proxy combo.
>
> Attila Kelemen <attila.kelemen85 at gmail.com> ezt írta (időpont: 2025. nov.
> 30., V, 20:51):
>
>> I think that is impossible. What I did when I needed something similar is
>> that I used an interface instead of a record and built utilities around it,
>> because in that case you can imitate what you want.
>>
>> That is, consider that you have `interface User { String firstName();
>> String lastName() }`. In this case, you could have methods taking a
>> `Function<User, T>` and then you can create an instance of `User` via
>> `Proxy.newProxyInstance` in which you record which method was called, and
>> pass the proxy instance to the `Function`. Assuming that someone passed
>> `User::firstName` for the `Function`, you can detect which method was
>> passed. The drawbacks are obvious, but it is better than passing strings in
>> my opinion.
>>
>> David Alayachew <davidalayachew at gmail.com> ezt írta (időpont: 2025. nov.
>> 30., V, 20:41):
>>
>>> Thanks for the response Attila.
>>>
>>> Let me try and loosen the constraints then -- is there any way for me to
>>> get a RecordComponent corresponding to firstName without needing to do
>>> String comparison?
>>>
>>> At the end of the day, that's all that I really need.
>>>
>>> As is now, the only way I can see to get a RecordComponent is to drill
>>> down from j.l.Class --> j.l.r.RecordComponent, then do String comparison
>>> against a provided String to get the record component that I want. That is
>>> unsafe and stringly typed, so, very much undesirable. After all, if I
>>> change my record to say first instead of firstName, I want a compiler
>>> error. But doing it that way, I won't -- I'll get a runtime error.
>>>
>>> So that's what I really want -- a type-safe way to isolate a record
>>> component from a record, without forcing my users to have to provide a
>>> String corresponding to the record component name.
>>>
>>> On Sun, Nov 30, 2025 at 2:16 PM Attila Kelemen <
>>> attila.kelemen85 at gmail.com> wrote:
>>>
>>>> I'm pretty sure there is no such thing, because that essentially
>>>> implies the existence of some kind of method literal (well, it would not be
>>>> strictly necessary, but the JLS would feel strange without it), and there
>>>> is no such thing (though it would be awesome, if there was).
>>>>
>>>> Also, note that if this was a thing, then your case is just a very
>>>> special case, and you would want more (I would for sure). That is, in that
>>>> case, I would also want type safety. So, something like
>>>> MethodReference<(MyRecord) -> String> (which of course would require
>>>> function types in Java).
>>>>
>>>> When I needed this, luckily I could restrain my need to interface
>>>> methods (as opposed to your record getters) where I could create a `Proxy`
>>>> and see which method gets called (nasty hack, has its downsides, but felt
>>>> like the safest to me).
>>>>
>>>> Attila
>>>>
>>>> David Alayachew <davidalayachew at gmail.com> ezt írta (időpont: 2025.
>>>> nov. 29., Szo, 20:50):
>>>>
>>>>> And by all means, add more parameters to foo if you want. For example,
>>>>> if a User.class helps, please do so!
>>>>>
>>>>> I just don't want to do anything like this.
>>>>>
>>>>> foo("firstName");
>>>>>
>>>>> That's stringly typed, and undesirable for my use case.
>>>>>
>>>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20251130/b8918d9b/attachment-0001.htm>
More information about the amber-dev
mailing list