-
Enhancement
-
Resolution: Unresolved
-
P3
-
None
-
None
-
None
There are currently several ways to wrap a MethodHandle in a functional interface type, which is often used to create a nicer interface for calling the method handle that can also be type-checked by javac.
If the target type is statically known, the MethodHandle can be wrapped using a lambda expression:
MethodHandle mh = ...
MyInterface mi = (a, b) -> {
try {
return mh.invokeExact(a, b);
} catch (Throwable t) {
// handle or ignore 't'
}
};
But, since the MethodHandle here is not a constant to the generated implementation type for the functional interface, the call through 'mh' can not typically be inlined.
If the target type is not statically known, there are 2 more options:
MethodHandleProxies::asInterfaceInstance​(Class<T>, MethodHandle)
Which has a nice API, but doesn't create a new type per MethodHandle, leading to degraded performance (for instance because the MH call can not be inline).
The last option is to rely on LambdaMetafactory to first create a metafactory, and then create a single instance. This has the desired performance characteristic, but is needlessly complex since this is a runtime API, and not meant to be used directly by users.
Proposal:
Add a simple API to MethodHandles.Lookup that combines the simplicity of MethodHandleProxies::asInterfaceInstance, with the performance characteristics of LambdaMetafactory (by spinning a new type for each MethodHandle).
If the target type is statically known, the MethodHandle can be wrapped using a lambda expression:
MethodHandle mh = ...
MyInterface mi = (a, b) -> {
try {
return mh.invokeExact(a, b);
} catch (Throwable t) {
// handle or ignore 't'
}
};
But, since the MethodHandle here is not a constant to the generated implementation type for the functional interface, the call through 'mh' can not typically be inlined.
If the target type is not statically known, there are 2 more options:
MethodHandleProxies::asInterfaceInstance​(Class<T>, MethodHandle)
Which has a nice API, but doesn't create a new type per MethodHandle, leading to degraded performance (for instance because the MH call can not be inline).
The last option is to rely on LambdaMetafactory to first create a metafactory, and then create a single instance. This has the desired performance characteristic, but is needlessly complex since this is a runtime API, and not meant to be used directly by users.
Proposal:
Add a simple API to MethodHandles.Lookup that combines the simplicity of MethodHandleProxies::asInterfaceInstance, with the performance characteristics of LambdaMetafactory (by spinning a new type for each MethodHandle).