Reflection on records
Chen Liang
chen.l.liang at oracle.com
Mon Dec 1 16:45:54 UTC 2025
Hi David, before we investigate solutions, what is the problem you want to resolve?
If you want to obtain a Method on a record class, you can do recordClass.getMethod("variable") to find that accessor method.
Note that the Java Virtual Machine does not validate a record, that it may recognize a class with the record attribute but has no corresponding accessor methods or canonical constructor as a record class.
-Chen
Confidential- Oracle Internal
________________________________
From: amber-dev <amber-dev-retn at openjdk.org> on behalf of David Alayachew <davidalayachew at gmail.com>
Sent: Monday, December 1, 2025 10:09 AM
To: Artyom Drozdov <artyomcool2 at gmail.com>
Cc: amber-dev <amber-dev at openjdk.org>
Subject: Re: Reflection on records
Thank you Artyom.
This mailing list is actually my final stop. I already asked in multiple other places.
And thanks for the suggestions about MethodHandles and InvokeDynamic. I think that might be overkill, so I'll probably just abandon the idea for now.
Either way, I sent a new message on the mailing list, asking for a new feature for records. All of the suggestions I've received thus far feel like trying to fit 10 pounds of dirt in a 5 pound bag. It feels like the language/compiler could step in and provide us with better tools.
On Mon, Dec 1, 2025, 9:57 AM Artyom Drozdov <artyomcool2 at gmail.com<mailto:artyomcool2 at gmail.com>> wrote:
Hello David,
If you absolute sure that you need that, it is possible to extract method name and signature from method reference (and access via MethodHandle or Reflections later) by analyzing class file and InvokeDynamic instruction (you probably will need some time to learn how it works if you are not familiar yet).
Personally, I'd prefer annotations + reflections + method handle approach (or drop the idea at all).
I also think that resources like StackOverflow might suit your goal better than amber-dev mailing list)
Regards,
Artyom Drozdov
пн, 1 дек. 2025 г., 15:47 David Alayachew <davidalayachew at gmail.com<mailto:davidalayachew at gmail.com>>:
Understood. Thanks @Stephen Colebourne<mailto:scolebourne at joda.org>.
And yes @Attila Kelemen<mailto:attila.kelemen85 at gmail.com>, I agree that it being an annotation does make it less ideal. Plus, I lose out on other things that the compiler might one day give us, like exhaustiveness checking. All in all, it is still the best solution, but not one I am a fan of.
On Mon, Dec 1, 2025, 4:55 AM Attila Kelemen <attila.kelemen85 at gmail.com<mailto:attila.kelemen85 at gmail.com>> wrote:
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<mailto: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<mailto: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/62d7edc3/attachment-0001.htm>
More information about the amber-dev
mailing list