简体   繁体   中英

How to chain MethodHandle invocations?

I have a problem where I have multiple methods with identical signatures (all returning void). I want to be able to combine the methodHandles for those methods to obtain a methodHandle that will invoke each method in turn.

The only way I have worked out to do this is with guardWithTest and I have an example of how I can make it work at: https://gist.github.com/gregw/b6c926fb44fd9a45b2c5afccaf7dcbf4

but the essence of the code is: ```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);

```

Is there an easier way to do this?

Supplemental question... should I want to do this or will it be just as fast to call the methodHandles in loop over a collection of method handles?

I think this might be better:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM