javajvmjava-7invokedynamicmethodhandle

MethodHandle - What is it all about?


I am studying new features of JDK 1.7 and I just can't get it what MethodHandle is designed for? I understand (direct) invocation of the static method (and use of Core Reflection API that is straightforward in this case). I understand also (direct) invocation of the virtual method (non-static, non-final) (and use of Core Reflection API that requires going through Class's hierarchy obj.getClass().getSuperclass()). Invocation of non-virtual method can be treated as special case of the former one.

Yes, I aware that there is an issue with overloading. If you want to invoke method you have to supply the exact signature. You can't check for overloaded method in easy way.

But, what is MethodHandle about? Reflection API allows you to "look on" the object internals without any pre-assumption (like implemented the interface). You can inspect the object for some purpose. But what is MethodHandle is designed too? Why and when should I use it?

UPDATE: I am reading now this http://blog.headius.com/2008/09/first-taste-of-invokedynamic.html article. According to it, the main goal is to simplify life for scripting languages that runs atop of JVM, and not for Java Language itself.

UPDATE-2: I finish to read the link above, some quotation from there:

The JVM is going to be the best VM for building dynamic languages, because it already is a dynamic language VM. And InvokeDynamic, by promoting dynamic languages to first-class JVM citizens, will prove it.

Using reflection to invoke methods works great...except for a few problems. Method objects must be retrieved from a specific type, and can't be created in a general way.<...>

...reflected invocation is a lot slower than direct invocation. Over the years, the JVM has gotten really good at making reflected invocation fast. Modern JVMs actually generate a bunch of code behind the scenes to avoid a much of the overhead old JVMs dealt with. But the simple truth is that reflected access through any number of layers will always be slower than a direct call, partially because the completely generified "invoke" method must check and re-check receiver type, argument types, visibility, and other details, but also because arguments must all be objects (so primitives get object-boxed) and must be provided as an array to cover all possible arities (so arguments get array-boxed).

The performance difference may not matter for a library doing a few reflected calls, especially if those calls are mostly to dynamically set up a static structure in memory against which it can make normal calls. But in a dynamic language, where every call must use these mechanisms, it's a severe performance hit.

http://blog.headius.com/2008/09/first-taste-of-invokedynamic.html

So, for Java programmer it is essentially useless. Am I right? From this point of view, It can be only considered as alternative way for Core Reflection API.

UPDATE-2020: Indeed, MethodHandle can be thought as s more powerful alternative to Core Reflection API. Starting with JDK 8 there are also Java Language features that use it.


Solution

  • Almost 9 years past since I've asked this question. JDK 14 is last stable version that has massive usage of MethodHandle... I've create mini-series of articles about invokedynamic https://alex-ber.medium.com/explaining-invokedynamic-introduction-part-i-1079de618512. Below, I'm quoting the relevant parts from there.

    MethodHandle can be thought as a more powerful alternative to Core Reflection API. MethodHandle is such an Object which stores the metadata about the method (constructor, field, or similar low-level operation), such as the name of the method signature of the method etc. One way took on it is a destination of the pointer to method (de-referenced method (constructor, field, or similar low-level operation)).

    Java code can create a method handle that directly accesses any method, constructor, or field that is accessible to that code. This is done via a reflective, capability-based API called MethodHandles.Lookup. For example, a static method handle can be obtained from Lookup.findStatic. There are also conversion methods from Core Reflection API objects, such as Lookup.unreflect.

    It is important to understand 2 key difference from Core Reflection API and MethodHandle.

    Basically, access check means whether you can access method (constructor, field, or similar low-level operation). For example, if the method (constructor, field, or similar low-level operation) is private, you can’t normally invoke it (get value from the field).

    As opposed to the Reflection API, the JVM can completely see-through MethodHandles and will try to optimize them, hence the better performance.

    Note: With MethodHandle you can also generate implementation logic. See Dynamical hashCode implementation. Part V https://alex-ber.medium.com/explaining-invokedynamic-dynamical-hashcode-implementation-part-v-16eb318fcd47 for details.