将MethodHandle转换为方法引用(此处为Function) [英] Convert MethodHandle to method reference (here Function)

查看:177
本文介绍了将MethodHandle转换为方法引用(此处为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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆