如何在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这太糟糕了。他们应该重新考虑在下一次更新中添加函数类型这个问题很有意义