Как связать вызовы MethodHandle? - PullRequest
       30

Как связать вызовы MethodHandle?

0 голосов
/ 24 октября 2018

У меня проблема, когда у меня несколько методов с одинаковыми сигнатурами (все возвращают 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 голосов
/ 24 октября 2018

Я думаю, что это может быть лучше:

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