【问题标题】:How to chain MethodHandle invocations?如何链接 MethodHandle 调用?
【发布时间】:2019-03-28 11:27:44
【问题描述】:

我有一个问题,我有多个签名相同的方法(都返回 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 一样快?

【问题讨论】:

    标签: java methodhandle


    【解决方案1】:

    我认为这可能会更好:

        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);
    

    【讨论】:

    • 您可以从前三个语句中删除.bindTo(test),然后将其应用于foldedABC。同样,避免执行三次MethodHandles.lookup(),而是将查找对象存储到局部变量中。除此之外,这似乎是链接调用的最简单方法。
    猜你喜欢
    • 2019-02-05
    • 2021-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-27
    • 2018-12-06
    相关资源
    最近更新 更多