Overview
A new feature in Java 7 provides a MethodHandle which "is a typed, directly executable reference to an underlying method, constructor, field, or similar low-level operation, with optional transformations of arguments or return values"This supports currying methods and many other features lambda based languages take for granted.
Note: this method compares invoke() in reflections and MethodHandles. I couldn't get invokeExact to work when returning a primitive (it got confused between int and Integer) However another benchmark Using Method Handles by Andrew Till indicated using invokeExact is much faster than using Method.invoke() with reflections. Thank you wensveen for the link.
Example
Say you have two methodpublic static int multiply(int i, int j) { return i * j; } public static int subtract(int i, int j) { return i - j; }With MethodHandle you can not only get a reference to the Method (like in reflection) but you can construct new MethodHandles. For example, you can bind the Object concerned or one of the arguments.
final Lookup lookup = lookup(); MethodHandle multiply = lookup.findStatic(MethodHandleMain.class, "multiply", methodType(int.class, int.class, int.class)); MethodHandle quadruple = insertArguments(multiply, 1, 4); System.out.println(multiply.invoke(3, 2)); // prints 6 System.out.println(quadruple.invoke(5)); // prints 20 MethodHandle subtract = lookup.findStatic(MethodHandleMain.class, "subtract", methodType(int.class, int.class, int.class)); MethodHandle subtractFromFour = insertArguments(subtract, 0, 4); MethodHandle fourLess = insertArguments(subtract, 1, 4); System.out.println(subtract.invoke(10, 5)); // prints 5 System.out.println(subtractFromFour.invoke(10)); // prints -6 System.out.println(fourLess.invoke(10)); // prints 6
Performance
This is very cool, but how does it perform? ;)There is a lot of potential for it to perform very well and the interface is cleaner than plain reflections however when comparing the alternatives, it doesn't perform as well as the alternatives in Java 7 (update 0)
Call method | Average time per call |
---|---|
Direct Method calls | 31 ns |
Reflections | 353 ns |
MethodHandle.invoke() | 5,378 ns |
No comments:
Post a Comment