«This answer»包含一个代码示例,展示了如何使用 Java 8 的 lambda 表达式和方法引用使用的相同功能将 a 转换MethodHandle
为函数实现。interface
这一切都是关于LambdaMetafactory.metafactory
使用方法句柄、所需的接口、唯一abstract
方法的名称和所需的签名进行调用。
方法的文档和它的类文档都非常详细。
因此,根据您的要求,示例代码可能如下所示:
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
是 rawinterface
函数签名的方法类型,所以对于 raw 类型Function
我们必须Object apply(Object)
在instantiatedMethodType
描述方法的同时实现Integer apply(String)
。这就是为什么在.generic()
第四个参数的 methodType 上调用该方法,该参数将转换(String)Integer
为(Object)Object
.
这对于构造函数来说更加棘手,因为构造函数将使用类型查找,(String)void
而函数类型static
与方法案例中的类型相同。因此,对于static
方法,该方法的MethodType
匹配MethodType
时间对于构造函数,我们必须使用不同的类型进行查找:
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();
但这只是为了完整性,对于Integer
你不应该调用构造函数但valueOf
最好使用方法的类型。