Shortcut for obtaining a MethodHandle for an anonymous code fragment
Florian Weimer
fw at deneb.enyo.de
Sat Nov 6 12:38:13 UTC 2021
* Vladimir Ivanov:
>> Is it true that there is no shortcut for obtaining a method handle for
>> some code fragment?
>>
>> That is, there is no way to write something like this?
>>
>> MethodHandle repeatIt = (String x) -> x + x;
>>
>> Instead it's necessary to give the expression a name and put it into a
>> static method somewhere, and obtain a MethodHandle for it using
>> MethodHandles.lookup().
>
> There's no language support for that, but you can write a utility method
> to convert a lambda into a method handle:
>
> wrapRunnable(() -> System.out.println(""));
>
> static MethodHandle wrapRunnable(Runnable r) {
> return RUNNABLE_RUN.bindTo(r);
> }
>
> static final MethodHandle RUNNABLE_RUN;
> static {
> try {
> RUNNABLE_RUN =
> MethodHandles.lookup().findVirtual(Runnable.class, "run",
> MethodType.methodType(void.class));
> } catch (NoSuchMethodException | IllegalAccessException e) {
> throw new InternalError(e);
> }
> }
I poked at the generated method handle with reflection, and it retains
a reference to the Runnable object with the synthesized lambda class.
Would it be a valid optimization if the lookup cut through to the
method implementing the lambda?
> Or even a generic version:
>
> wrap(Runnable.class, () -> System.out.println(""));
>
> static <T> MethodHandle wrap(Class<T> functionalInterface, T lambda) {
> MethodHandle sam = ... // find SAM in a functional interface
> return sam.bindTo(lambda);
> }
This is an interesting use of a comment. Is there even a well-defined
concept of a functional interface at the JVM level? I guess it's
possible to ignore JLS-level override equivalence and generics, and
focus on the generic signatures only.
Still it would be nice to have something in the JDK to compute a
JVM-level SAM at run time.
More information about the mlvm-dev
mailing list