将MethodHandle转换为方法引用(此处为Function) [英] Convert MethodHandle to method reference (here Function)
问题描述
MethodType methodType = MethodType.methodType(void.class, ByteBuffer.class);
MethodHandle handle = MethodHandles.publicLookup().findConstructor(type, methodType);
Function<ByteBuffer, Object> = handle; // ???
是否有可能获得最后的作业?反转方式不起作用:是否可以将方法引用转换为MethodHandle?
Is it possible to get the last assignment work? The inverted way does not work: Is it possible to convert method reference to MethodHandle?
这是另一个可复制的例子:
Here another and copy-pastable example:
new Integer("123");
MethodType methodType = MethodType.methodType(void.class, String.class);
MethodHandle handle = MethodHandles.publicLookup().findConstructor(Integer.class, methodType);
Function<String, Integer> function1 = Integer::new;
Function<String, Integer> function2 = handle.toLambda(); // ???
推荐答案
«这个答案»包含一个代码示例,显示如何将 MethodHandle
转换为功能界面
使用相同功能的实现,Java 8的lambda表达式和方法引用使用。
«This answer» contains a code example showing how to convert a MethodHandle
to a functional interface
implementation using the same feature, Java 8’s lambda expressions and method references use.
这都是关于调用 LambdaMetafactory.metafactory
使用方法句柄,所需的接口和唯一的 abstract
方法和所需签名的名称。
It’s all about calling LambdaMetafactory.metafactory
with the method handle, the desired interface and the name of the sole abstract
method and required signature.
因此,对于您的请求,示例代码可能如下所示:
So, for your request, example code may look like this:
MethodType methodType = MethodType.methodType(Integer.class, String.class);
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle handle = lookup.findStatic(Integer.class, "valueOf", methodType);
Function<String,Integer> f=(Function<String,Integer>)
LambdaMetafactory.metafactory(lookup, "apply",
MethodType.methodType(Function.class), methodType.generic(),
handle, methodType).getTarget().invokeExact();
System.out.println(f.apply("123"));
您必须关注此处的签名类型。第四个参数 samMethodType
引用原始接口
的函数签名的方法类型,因此对于原始类型函数
我们必须实现 Object apply(Object)
,而 instantiatedMethodType
描述方法 Integer apply(String)
。这就是为什么方法 .generic()
在methodType上调用第四个参数,它将转换(String)Integer
到(对象)对象
。
You have to care about the signature types here. The fourth parameter samMethodType
refers the the method type of the raw interface
’s functional signature, so for the raw type Function
we must implement Object apply(Object)
while the instantiatedMethodType
describes the method Integer apply(String)
. That’s why the method .generic()
is called on the methodType for the fourth parameter which will convert (String)Integer
to (Object)Object
.
这对于构造函数来说更加棘手,因为构造函数将被查找为(String)void
类型,而功能类型与 static
方法案例中的相同。因此,对于 static
方法,方法的 MethodType
匹配 MethodType
而对于构造函数,我们必须使用不同的类型进行查找:
This is even trickier for constructors as the constructor will be looked up with a (String)void
type while the functional type is the same as in the static
method case. So for a static
method the method’s MethodType
matches the MethodType
while for a constructor we have to use a different type for the lookup:
MethodType methodType = MethodType.methodType(Integer.class, String.class);
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle handle = lookup.findConstructor(
Integer.class, MethodType.methodType(void.class, String.class));
Function<String,Integer> f=(Function<String,Integer>)
LambdaMetafactory.metafactory(lookup, "apply",
MethodType.methodType(Function.class), methodType.generic(),
handle, methodType).getTarget().invokeExact();
但这只是为了完整性,类型整数
你不应该调用构造函数,但最好使用 valueOf
方法。
But that’s only for completeness, for the type Integer
you shouldn’t call the constructor but use valueOf
method, preferably.
这篇关于将MethodHandle转换为方法引用(此处为Function)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!