[External] : Re: Method and Field Literals

Brian Goetz brian.goetz at oracle.com
Sun Apr 24 15:31:39 UTC 2022

So, a feature where field and method literals evaluated only to Method objects is a pretty weak one, and worse, fi the goal is merely to pull the reflection API into the language, is likely to result in requests to pull further.  Though I do enjoy the extra type checking that IntelliJ gives me for method and method handle lookup.)

The reality is that Method is not a very useful type; reflection is an escape hatch, which has more benefit for frameworks than for ordinary user code.  You might say “but we have class literals”, but this is mostly a “for consistency” argument*, and one that doesn’t even survive much scrutiny.

Class literals have two aspects that method literals would not: their role in inference (Foo.class has type Class<Foo>, meaning that it can be used as a source of constraints in type inference), and the Object::getClass method.  Method and field literals would have neither of these two touch points.  (If it were not for the type inference aspect, if we didn’t have class literals now, I might not be inclined to add them — Class::forName works  too.)  So I would rate this a pretty weak feature.

The main reason method references are useful and these are less useful is that methods have behavior, and method refs allow you to access that behavior through the suitable abstraction level (e.g., Function, Supplier.)  Passing around Method or MethodHandle or VarHandle is not particularly desirable for ordinary application code.

There’s a version of method (and field) references that is more interesting, where we can use target typing to let Foo::bar evaluate to a SAM type, Method, MethodHandle, MethodDesc, or other description of a method.  (Note that you also have to pull in additional syntax and behavior to support overload selection, since we don’t have a SAM type to guide the overload selection.)  That’s more interesting, but a more complex feature.  Fields are even more complicated, because fields have TWO behaviors, and the obvious representations (Field, VarHandle) are also pretty low-level and unsuitable to application-level interaction.  (If the language had Properties, then turning a field into a Property would be a more appropriate API-level encoding.)

*If the best argument you can make for a feature is “for consistency”, that’s usually a sign that the feature is weak.

On Apr 24, 2022, at 5:31 AM, arjan tijms <arjan.tijms at gmail.com<mailto:arjan.tijms at gmail.com>> wrote:


On Sun, Apr 24, 2022 at 1:17 AM Ethan McCue <ethan at mccue.dev<mailto:ethan at mccue.dev>> wrote:
Before moving on with the discussion, can you also address Brain Goetz's questions directly?

1. what do you expect the _type_ of a method literal is?


2. Is it a goal to have
    a. earlier error checking that you specified a method that exists
    b. syntactic sugar for the reflective call
    c. the lookup can be more efficient


And then from me

3. What in your first example disqualifies a normal method reference lambda (Class::method) from being appropriate?

If you mean the Query example:

criteriaQuery.select(root).where(cb.equal(root.get(Student_.gradYear), 2015));

Then it's not about the actual value of Student.gradYear at this point, but about the identity of the property. It's used to (ultimately) generate SQL. The property (field, method) needs to be identified, in order to read annotations from it that specify the mapping.

If you mean the handler and interceptor examples, then it's checking that an invoked (intercepted / handled) method is the intended method.

4. This pattern of

    var thing = Lookup.find("externalUncheckedName", TypeA.class, TypeB.class)
    var result = (TypeB) thing.invoke(new TypeA()); // Object... as arg type and throws some exceptions

is also used in the API for Panama. If we are going to add new goo, is there a way to address this sort of API as well?

Is "externalUncheckedName" a method name there?

Kind regards,
Arjan Tijms

More information about the discuss mailing list