DynamicIndy
There is no way to invoke invokedynamic using the Java language. So testing invokedynamic is not that obvious if you don’t have your own dynamic language.
I’ve developed a small class DynamicIndy that uses ASM 4.0 (not an official release) to generate a static method that calls invokedynamic. These static method is after converted to a MethodHandle that can be called in Java
The code is available at the bottom of this post
How to use it ?
DynamicIndy defines a method named (judiciously
invokedynamic that takes a name and a MethodType, a way to specify a bootstrap method (a triple class, method name, method type ) and some optional arguments for the bootstrap method.
The following code shows how to create a BigDecimal constant using invokedynamic.
This code shows how to use it:
public class DynamicIndyTest {
public static CallSite bsm(Lookup lookup, String name, MethodType methodType, Object arg) {
System.out.println("construct the BigDecimal constant "+arg);
return new ConstantCallSite(
MethodHandles.constant(BigDecimal.class, new BigDecimal(arg.toString())));
}
public static void main(String[] args) throws Throwable {
DynamicIndy dynamicIndy = new DynamicIndy();
MethodHandle mh = dynamicIndy.invokeDynamic("_", MethodType.methodType(BigDecimal.class),
DynamicIndyTest.class, "bsm", MethodType.methodType(CallSite.class, Lookup.class, String.class, MethodType.class, Object.class),
"1234567890.1234567890"
);
System.out.println((BigDecimal)mh.invokeExact());
System.out.println((BigDecimal)mh.invokeExact());
}
}
If you run this code
java -XX:+UnlockExperimentalVMOptions -XX:+EnableInvokeDynamic
-cp .:asm-all-4.0-beta1.jar DynamicIndyTest
it will print
construct the BigDecimal constant 1234567890.1234567890
1234567890.1234567890
1234567890.1234567890
As you see the bootstrap method is called once and the constant reused.
cheers,
Rémi