如何在Java8中间接运行方法引用?
一般问题如下:如何在Java8中间接运行方法引用?,java,lambda,java-8,Java,Lambda,Java 8,一般问题如下: 使用语法object::aMethod时,是否可以将其转换为MethodHandle等类型作为功能接口 如果没有,如果可能的话,如何在Java8中间接调用方法引用 例如,假设我们想要一个MethodRefRunner,如下所示: class MethodRefRunner { static void execute(Object target, WHATTYPE mref, Object... args) { mref.apply(args); } } 它可
- 使用语法
时,是否可以将其转换为object::aMethod
等类型作为功能接口MethodHandle
- 如果没有,如果可能的话,如何在Java8中间接调用方法引用
MethodRefRunner
,如下所示:
class MethodRefRunner {
static void execute(Object target, WHATTYPE mref, Object... args) {
mref.apply(args);
}
}
它可以用作:MethodRefRunner.execute(o,o::someMethod,someParam)
在上面的代码片段中,WHATTYPE
的一个选项是java.util.function.function
,但限制性很强。如前所述,在版本b75之前,有一个java.util.function.Block
可用,可能很方便
另一方面,WHATTYPE
是否有可能以某种方式转换为java.lang.invoke.MethodHandle
Java专家注意:请根据需要修改问题的标题。我认为没有任何方法可以满足您的要求。什么类型必须是一个函数接口,不一定是
Function
,而是一个其单个抽象方法与somethod
匹配的接口。它是一种普通的接口类型,受Java类型的常规规则约束java.util.function.Block
是这样一种普通的接口类型,在您看来并不特殊。(顺便说一句,它仍然存在,现在被称为Consumer
)方法引用的工作原理与lambda一样,与lambda一样,它本身没有“类型”。它的类型取决于使用它的上下文。所以你的问题没有真正意义。如果在调用此MethodRefRunner.execute()
方法时使用该方法引用,则该方法引用的类型将是WHATTYPE
(无论是什么)的实例,因为该方法声明接受该实例。如果您是从其他地方得到的,那么,那个地方就会知道它是什么类型的。谢谢您的回答。现在的问题是,有没有办法在运行时将方法引用(或lambda表达式)转换为MethodHandle
,以便调用它?对不起,我认为答案仍然是否定的。原因(AFAIK)是,任何这样做的方法都必须以特定lambda实现的形式有一个固定的起点。但目的不是约束实现——运行时可以选择“动态旋转的内部类、围绕方法句柄的包装类、动态代理、方法句柄代理或其他未知机制”。(). 因此,如果事实上有某种方法可以做你想要的事情,它总是依赖于虚拟机。我在2012年11月发现了一条讨论线索,但不清楚这是否有任何进展:在Scala中,你可以强制一个方法成为一个函数值,这是eta扩展(Scala中的方法和函数之间存在差异)。至于您所描述的情况,Scala编译器足够聪明,可以同时接受这两种类型。@铍确实是很好的对比,这也是为什么我想知道Java 8没有选择它的原因。@nobeh Java 8坚持使用函数接口,因为添加函数类型会对语言进行更大的更改。他们可能会晚一点来。@nobeh这太糟糕了。他们应该重新考虑在下一次更新中添加函数类型这个问题很有意义