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 <[email protected]> on behalf of David Alayachew 
<[email protected]>
Sent: Monday, December 1, 2025 10:09 AM
To: Artyom Drozdov <[email protected]>
Cc: amber-dev <[email protected]>
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 
<[email protected]<mailto:[email protected]>> 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 
<[email protected]<mailto:[email protected]>>:
Understood. Thanks @Stephen Colebourne<mailto:[email protected]>.

And yes @Attila Kelemen<mailto:[email protected]>, 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 
<[email protected]<mailto:[email protected]>> 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 <[email protected]<mailto:[email protected]>> 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 
<[email protected]<mailto:[email protected]>> 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

Reply via email to