Let me replay some analysis that was done on this topic in the past.

There are two separate things going on here:

 - Can we use symbolic constants instead of string constants to do reflective 
lookups
 - Can we have more kinds of symbolic reflective constants (field literals, 
method literals, record component literals, method handle literals, etc.)

The first one is more shallow; David is exploiting a special case of records 
where (a) there is already a method reference form for accessors, which could 
potentially be bootstrapped into service here and (b) very luckily, the shape 
of all such accessor method references vary only parametrically in shape.  So 
one could write a method:

    interface AccessorShape<T, U> {
        U access(T t);
    }

    <R extends Record, U> RecordComponent component(Accessor<R, U> c) { … }

Which would allow us to say

    RecordComponent rc = component(Foo::component)

Where the parameter is a method reference but from which we can strip-mine the 
name and type and turn it into a component lookup.  That’s a clever trick, and 
there is no intrinsic reason why we couldn’t do this, but it doesn’t scale 
beyond this particular case.  Field and method lookups would still use strings 
and could fail at runtime for all the reasons.

The second is one that was explored fairly deeply during Lambda.  Reflective 
literals for jlr.{Field,Method,Constructor} are an obvious move, and have a few 
challenges, some of which are workable, but the biggest of which is: 
overloading.  With method reference targeted at functional interfaces, the 
functional interface provides a signature shape with which we can do overload 
selection.  But if we had an overloaded method m, then

    Method m = Foo::m

We have no information with which to select the proper m.  (Please, don’t take 
this as an invitation for a syntax discussion; they’ve all been explored, and 
besides, there are deeper problems here than syntax.)


On Dec 1, 2025, at 12:13 PM, Archie Cobbs 
<[email protected]<mailto:[email protected]>> wrote:

I'm guessing what underlies David's question is this thought: Why can't the 
compiler provide more compile-time checking of Field and Method reflection 
objects?

After all, it does this for Class objects by providing us with Class literals 
(remember in the old days you could only obtain them via Class.forName()).

I have wondered the same thing, though I also appreciate that the devil is in 
the details.

For example, David's question could be addressed by adding Method and Field 
literals:

public class Foo {
    public static void meth(int x) { ... }
}

Method m = Foo::meth.method;
m.invoke(123);

Of course, this is still imprecise because Method is not generic and so this 
would fail if there were overloads, among other problems.

So I think the intuition is valid. Whether a practical solution exists is 
another question.

-Archie

On Mon, Dec 1, 2025 at 10:46 AM Chen Liang 
<[email protected]<mailto:[email protected]>> wrote:
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.
--
Archie L. Cobbs

Reply via email to