如何链接MethodHandle调用?

时间:2018-10-24 06:34:55

标签: java methodhandle

我有一个问题,我有多个具有相同签名的方法(所有方法都返回void)。我希望能够将这些方法的methodHandles组合在一起,以获得一个将依次调用每个方法的methodHandle。

我解决此问题的唯一方法是使用guardWithTest,我有一个如何使其工作的示例:https://gist.github.com/gregw/b6c926fb44fd9a45b2c5afccaf7dcbf4

但是代码的本质是: ```java

    TestMethodHandle test = new TestMethodHandle();

    MethodHandle callA = MethodHandles.lookup().findVirtual(TestMethodHandle.class,"callA", methodType(Void.TYPE, String.class, Integer.TYPE)).bindTo(test);
    MethodHandle callB = MethodHandles.lookup().findVirtual(TestMethodHandle.class,"callB", methodType(Void.TYPE, String.class, Integer.TYPE)).bindTo(test);
    MethodHandle callC = MethodHandles.lookup().findVirtual(TestMethodHandle.class,"callC", methodType(Void.TYPE, String.class, Integer.TYPE)).bindTo(test);

    MethodHandle asGuard = MethodHandles.lookup().findStatic(TestMethodHandle.class,"alwaysTrue", MethodType.methodType(Boolean.TYPE));
    MethodHandle guardA = MethodHandles.filterReturnValue(callA,asGuard);
    MethodHandle guardB = MethodHandles.filterReturnValue(callB,asGuard);
    MethodHandle guardC = MethodHandles.filterReturnValue(callC,asGuard);

    MethodHandle empty = empty(methodType(Void.TYPE, String.class, Integer.TYPE));

    MethodHandle invokeC = MethodHandles.guardWithTest(guardC,empty,empty);
    MethodHandle invokeBC = MethodHandles.guardWithTest(guardB,invokeC,empty);
    MethodHandle invokeABC = MethodHandles.guardWithTest(guardA,invokeBC,empty);

    invokeABC.invoke("chained", 2);

```

有更简单的方法吗?

补充问题...我应该这样做还是以循环方式调用方法句柄集合上的methodHandles一样快?

1 个答案:

答案 0 :(得分:0)

我认为这可能更好:

    MethodHandle callA = MethodHandles.lookup().findVirtual(TestMethodHandle.class,"callA", methodType(Void.TYPE, String.class, Integer.TYPE)).bindTo(test);
    MethodHandle callB = MethodHandles.lookup().findVirtual(TestMethodHandle.class,"callB", methodType(Void.TYPE, String.class, Integer.TYPE)).bindTo(test);
    MethodHandle callC = MethodHandles.lookup().findVirtual(TestMethodHandle.class,"callC", methodType(Void.TYPE, String.class, Integer.TYPE)).bindTo(test);

    MethodHandle foldedABC = MethodHandles.foldArguments(MethodHandles.foldArguments(callC,callB),callA);
    foldedABC.invoke("folded", 42);