SoFunction
Updated on 2025-05-12

Detailed explanation of the use of Java MethodHandle

Use of Java MethodHandle

MethodHandle in Java is a new mechanism introduced in Java SE 7 for dynamically calling methods.

Here is a detailed explanation of Java MethodHandle:

definition

  • MethodHandle:yesAn instance of , it is a direct executable reference to a method in Java (including instance methods, static methods, constructors, etc.).

Features

  1. Lightweight and efficient: Compared to traditional Java reflection, MethodHandle is lighter and more efficient because it bypasses many of the additional overhead of reflections, such as access control checking, etc.
  2. Directly executable: MethodHandle is a direct reference to the method. You can call the target method directly through the MethodHandle object, without first getting the Method object like reflection.
  3. Typed: MethodHandle has the feature of type checking. At compile time, it will check whether the type of MethodHandle matches the type of the target method.

Usage process

Introducing JDK: Ensure that the development environment has introduced the JDK version (Java SE 7 and above) that supports MethodHandle.

Create a MethodHandle object

  • useClassiclookup()Method to get oneObject.
  • useThe object'sfindStatic(), findVirtual(), findSpecial(), findConstructor()etc. to find and get the MethodHandle object of the target method.

Bind MethodHandle to target method(If needed):

  • If MethodHandle points to an instance method, you can useMethodHandleThe object'sbindTo()Method binds it to the target instance.

Calling the target method

  • Using MethodHandle objectinvoke()invokeExact()invokeWithArguments()etc. to call the target method.

The difference from reflection

  • performance: MethodHandle is usually faster than reflection because it bypasses the extra overhead of many reflections.
  • Type safety: MethodHandle performs type checking at compile time, while reflection performs type checking at runtime, which may causeClassCastExceptionetc.
  • usage: Reflection needs to be obtained firstMethodObject, and MethodHandle directly references the method.

Example:

import ;
import ;
import ;

public class MethodHandleExample {
    public static void main(String[] args) throws Throwable {
        // Find the startsWith method of String class        MethodHandle handle = ()
                .findVirtual(, "startsWith", (, ));

        // Call the startsWith method        boolean result = (Boolean) ("Hello, World!", "Hello");

        (result); // Output: true    }
}

When using JavaWhen calling an instance method, you need to first get the instance methodMethodHandle, then you can useinvoke()invokeExact()orinvokeWithArguments()method to call it.

The following is usedinvokeExact()An example of a method calling an instance method:

import ;
import ;
import ;

public class MyClass {
    public int myMethod(String param, int number) {
        ("Inside myMethod: " + param + ", " + number);
        return number * 2;
    }

    public static void main(String[] args) throws Throwable {
        // Create an instance of MyClass        MyClass obj = new MyClass();

        // Find the MethodHandle of myMethod        // Note: Since we are looking inside MyClass, we can use ()        // In actual application, if MyClass is a class in other packages, you may need different Lookup instances        MethodHandle mh = ()
                .findVirtual(, "myMethod", (, , ));

        // Call myMethod using invokeExact        // Note: invokeExact requires strict matching of parameter types, including return types        int result = (int) (obj, "Hello", 42);

        // Output result        ("Result: " + result);
    }
}

In the example above, we first create aMyClassExamplesobj. Then, we use().findVirtual()Method searchmyMethodofMethodHandle

Notice,findVirtualThe method requires three parameters: the target classClassobject, method name and a description method signatureMethodTypeObject.

Get itMethodHandleAfter that, we useinvokeExactMethod to callmyMethod. becausemyMethodThe return type isint, and it accepts aStringAnd oneintAs parameter, so we pass the correct parameter type toinvokeExact, and a cast is used to transfer the result fromObjectConvert toint

Differences between invoke(), invokeExact(), and invokeWithArguments()

In JavaIn the package,MethodHandleClasses provide several different methods to dynamically call target methods. The following isinvoke()invokeExact()andinvokeWithArguments()The main differences between these three methods:

1. invoke()

Features

  • invoke()Method is a common method of MethodHandle, which allows type conversion to be performed when called.
  • If the provided parameter type does not match the target method,invoke()Will try to useMethodHandleofasType()Method for parameter adaptation.

parameter

  • invoke()Method accepts a list of variable parameters (Object... args), where the first parameter (if the target method is an instance method) is an instance object, and subsequent parameters are parameters passed to the target method.

Example

MethodHandle mh = ... // Get an instance of MethodHandleObject result = (obj, arg1, arg2, ...);

2. invokeExact()

Features

  • invokeExact()The method provides strict type checking.
  • If the provided parameter type does not match the parameter type of the target method,invokeExact()Will throwWrongMethodTypeException

parameter

  • invokeExact()Also accepts a variable parameter list (Object... args), but requires that the types of these parameters must exactly match the parameter type of the target method.

Example

MethodHandle mh = ... // Get an instance of MethodHandleObject result = (obj, arg1, arg2, ...); // Ensure the type matches

3. invokeWithArguments()

Features

  • invokeWithArguments()Methods allow useList<Object>Called as a parameter list.
  • This provides a more flexible way for callers to build parameter lists, especially when the number of parameters is uncertain or dynamically built is required.

parameter

  • invokeWithArguments()Accept oneList<Object>Parameters, where the first element (if the target method is an instance method) is an instance object, and the subsequent element is the parameter passed to the target method.

Example

MethodHandle mh = ... // Get an instance of MethodHandleList&lt;Object&gt; arguments = (obj, arg1, arg2, ...);
Object result = (arguments);

4. Inclusion

  • invoke(): Provides flexible calls for type adaptation, allowing parameter types to be converted at runtime.
  • invokeExact(): Provides strict type checking, requiring the parameter type to exactly match the target method.
  • invokeWithArguments(): Allows to use lists as parameters to call, providing greater flexibility.

When choosing which method to use, it should be decided based on the specific needs. If you want to perform strict type checks, you can useinvokeExact();If you need a more flexible parameter transfer method, you can consider usinginvoke()orinvokeWithArguments(). At the same time, it should be noted thatinvokeExact()The performance is usually better thaninvoke(), because it avoids the overhead of type adaptation at runtime.

Summarize

Java's MethodHandle provides an efficient, lightweight and type-safe method to dynamically call Java methods. Through MethodHandle, developers can operate methods in Java code more flexibly and efficiently.

The above is personal experience. I hope you can give you a reference and I hope you can support me more.