Локальные переменные в MethodHandle
java.lang.invoke.MethodHandle
и друзья позволяют генерировать исполняемый код, отвечающий требованиям JIT, с помощью ряда комбинаторов.
Как я могу создать локальные переменные в MethodHandles? В идеале метод подписи, который я хочу, выглядит примерно так
MethodHandle withLocalVariable(
Class<?> varClazz, Function<VarHandle, MethodHandle> usingVar)
хотя я не уверен VarHandle
на самом деле вполне правильная абстракция.
Обратите внимание, что просто создать переменную-держатель недостаточно хорошо - я хочу разные вызовы MethodHandle
использовать разные переменные.
1 ответ
Вы не можете создать локальную переменную. Если вы хотите использовать значение несколько раз, вы можете создать сквозную передачу с identity
а затем скопируйте значение с помощью permuteArguments
(или просто использовать permuteArguments
сам по себе, если вы можете) например:
MethodHandle start = identity(String.class);
MethodHandle sideEffect = lookup().findVirtual(PrintStream.class, "println", methodType(void.class, String.class)).bindTo(System.out);
MethodHandle result = collectArguments(start, 0, sideEffect); // sideEffect needs to return nothing
result = permuteArguments(result, methodType(String.class, String.class), 0, 0); // copy argument
System.out.println((String) result.invokeExact("Hello")); // Hello\nHello
Где переданный аргумент используется как в качестве аргумента дескриптора побочного эффекта, так и в качестве возвращаемого значения. По сути, вы можете использовать значение несколько раз.
Но на самом деле нет простого универсального ответа, когда дело доходит до дескрипторов методов. Возможно, лучший совет, который я могу дать, это стараться не использовать их как можно больше. т.е. напишите статический метод с нужным вам кодом, а затем используйте дескриптор метода для этого в более длинной цепочке дескрипторов метода.