Java 7 : More dynamics

Like you know (or perhaps not, nevermind), the Java bytecode doesn't support dynamic method invocation. There are three supported invocations modes : invokestatic, invokespecial, invokeinterface or invokevirtual. These modes allows to call methods with known signature. We talk of strongly typed language. This allows to to make some checks directly at compile time.

On the other side, the dynamic languages use dynamic types. So we can call a method unknown at the compile time, but that's completely impossible with the Java bytecode. The dynamic languages based on the Java Runtime must use Java Reflection to make dynamic invocations.

In Java 7, we'll see a new feature, the JSR 292. This JSR add new method invocation mode : invokedynamic. With that new bytecode keyword, we can call method only known at runtime.

This JSR only impact the bytecode not the language. But with Java 7 we'll see a new package java.dyn that use this new functionality. That package will improve the performances of Java reflection and mainly the performances of the others languages that run in the JVM.

MethodHandle

The MethodHandle class allows to manipulate a reference to a method. It's like a pointer to a method. With that features, we avoid the heavy process of reflection.

With that class, we can have informations about the method (return type and parameters) and invoke that method with a special invoke() method that can be called with any number of parameters. To create a MethodHandle we use the MethodHandles factory.

Here is an example :

JComboBox combo = new JComboBox();

MethodHandle handle = MethodHandles.lookup().findVirtual(JComboBox.class, "setModel", MethodType.make(void.class, ComboBoxModel.class));

handle.invoke(combo, new CustomComboModel());

Of course, this example is completely useless but shows the process of invoking a method using Method. There are some differences with Reflection :

  • The call to invoke() is optimized by the JVM with calling directly the target method like any other call.
  • The performances are a lot better, almost the same as a standard call.
  • The cheks on the method are made when we create the MethodHandle Object not at all the invoke() calls.

InvokeDynamic

The second class of this new package is the InvokeDynamic class. This is even more weird than the first one, because this class has no methods. But we can invoke any methods on it.

InvokeDynamic.setModel(new CustomComboModel());
InvokeDynamic.init();
Date today = InvokeDynamic.getDate();
//... You can call any valid method

All that calls will be compiled with InvokeDynamic. Namely, all that calls will not be checked at compile time but at runtime.

To use that mechanism, we must define a bootstrap mechanism who will do the conversion between the method calls on InvokeDynamic and the really Method (through MethodHandle) to invoke. When we invoke the method, the JVM use that bootstrap method to get the MethodHandle and invoke it.The JVM use a cache for the MethodHandle to improve performances. So, only the first dynamic call will be searched in the bootstrap method.

To register the bootstrap method, we have to use the Linkage.registerBootstrapMethod(String methodName) method.

Here is a really basic example of a boot strap method. That method only use the name of the called method and return the MethodHandle to the same method in the Utility class with no args. Of course, that kind of bootstrap method must not be used, but that shows the basics of develop that kind of methods.

private static CallSite bootstrap(Class caller, String name, MethodType type) {
    CallSite site = new CallSite(caller, name, MethodType.make(void.class));
    site.setTarget(MethodHandles.lookup().findStatic(Utility.class, name, MethodType.make(void.class)));
    return site;
}

References of type InvokeDynamic can take any types of objects :

InvokeDynamic dynamicString = "Hello World";
InvokeDynamic dynamicCombo = new JComboBox();
InvokeDynamic dynamicNumber = 1;

With that, we can dynamically call a method on the target :

dynamicString.aSimpleMethod();

Here we are. I think we've covered the main features of this new package.

Of course these classes will mostly be used by dynamic languages developers instead of standard programmers but the MethodHandle class can be useful to improve reflection performances in simple programs. I think it's a great new features but that will not be used by everybody.

Related articles

  • Java 7 : Add "public defender methods" to Java interfaces
  • Java 7 has been released!
  • The reserved keywords of the Java Language
  • Mock objects with EasyMock
  • Java 7 : Languages updates from Project Coin
  • Java 7 : The new java.util.Objects class
  • Comments

    Comments powered by Disqus