使用MethodHandles和invokedynamic进行链式方法调用

时间:2017-09-22 15:25:44

标签: java lambda jvm bytecode invokedynamic

考虑一种动态的,谓词的方面语言。可以调用方面(即方法)而不是之前之后原始方法。打开和关闭这些方面,这在运行时发生。甚至可能是,多个方面想要改变相同的方法,这将导致这些方面的组合成为方法调用链。

原始方法由加载时编译器(JPLIS和ASM)更改。我得到了一些像这样的字节码:

//## baseMethod ##
aload 0         // this
aload ...       // some more arguments
invokedynamic # // call the bootstrap method which returns a callsite to be invoked

有趣的是,bootstrap方法应该以特定的方式工作:

  • 使用兼容的参数列表返回方法的串联。这些MethodHandle绑定到调用它们的不同类型的不同实例。
  • 结果MethodHandle可能只是绑定到其他实例,而不是绑定到调用bootstrap方法的实例。因此,应省略使用 this 调用生成的调用点(下面替代方案中的第一个分支)。

也可能直接调用原始方法,这是完全可以的。

enter image description here

在我看来,MethodHandle是正确的做法。 我的问题是如果一切都可以在单个bootstrap方法中实现,那么我可以链接方法调用,如序列图所示,使用从绑定到bootstrap方法返回的方法句柄链呼叫网站。

1 个答案:

答案 0 :(得分:3)

任何分支逻辑将决定应用于方法调用的哪些方面必须在方法句柄执行时运行,而不是在引导时运行。

您可以通过左MethodHandles.guardWithTest​(test, target, fallback)

组合各种手柄和分支逻辑

堆栈上的this将是句柄的参数之一。