Идея invokedynamic
есть; При первом обнаружении этого байт-кода вызовите метод начальной загрузки, который создает объект Callsite
, который ссылается на фактический метод, который необходимо вызвать.
На практике это часто означает, что вы динамически создаете реализацию для вызова.
Если вы посмотрите на вашу программу с javap -v test
, вы увидите внизу атрибут BootstrapMethods
:
BootstrapMethods:
0: #15 REF_invokeStatic java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
Method arguments:
#16 Hello \u0001 World!
Где вы можете видеть, что метод начальной загрузки для этого конкретного места вызова находится в StringConcatFactory
Method arguments
- набор постоянных аргументов.
Ведущие аргументы Lookup
, String
и MethodType
соответственно; объект поиска с теми же привилегиями, что и у места вызова, с некоторым именем и типом места вызова. Первый из них должен быть предоставлен виртуальной машиной во время выполнения, а последние 2 - в записи пула констант динамических переменных в форме имени и типа:
#2 = InvokeDynamic #0:#17 // #0:makeConcatWithConstants:(I)Ljava/lang/String;
Таким образом, для реализации этого байт-кода у вас должно быть какое-то оборудование для создания объекта поиска, а затем вы сможете вызвать метод начальной загрузки. После этого вы можете вызвать dynamicInvoker()
для возвращенного объекта Callsite
, который дает вам MethodHandle
, который вы должны затем кэшировать для этого конкретного места вызова и затем (наконец) вызвать .
Если вы хотите посмотреть, как это реализовано в OpenJDK, вы можете найти реализацию здесь: http://hg.openjdk.java.net/jdk/jdk/file/tip/src/hotspot/share/interpreter/bytecodeInterpreter.cpp#l2446
Я предполагаю, что это, вероятно, слишком сложно на этом раннем этапе проекта, так что на данный момент может быть проще скомпилировать вашу программу с -XDstringConcat=inline
, поскольку она использует устаревшую конкатенацию StringBuilder
, которая должна быть проще реализовать.