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:yes
An instance of , it is a direct executable reference to a method in Java (including instance methods, static methods, constructors, etc.).
Features
- 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.
- 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.
- 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:
- use
Classic
lookup()
Method to get oneObject.
- use
The object's
findStatic()
,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 use
MethodHandle
The object'sbindTo()
Method binds it to the target instance.
Calling the target method:
- Using MethodHandle object
invoke()
、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 cause
ClassCastException
etc. -
usage: Reflection needs to be obtained first
Method
Object, 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 method
MethodHandle
, 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 aMyClass
Examplesobj
. Then, we use().findVirtual()
Method searchmyMethod
ofMethodHandle
。
Notice,findVirtual
The method requires three parameters: the target classClass
object, method name and a description method signatureMethodType
Object.
Get itMethodHandle
After that, we useinvokeExact
Method to callmyMethod
. becausemyMethod
The return type isint
, and it accepts aString
And oneint
As parameter, so we pass the correct parameter type toinvokeExact
, and a cast is used to transfer the result fromObject
Convert toint
。
Differences between invoke(), invokeExact(), and invokeWithArguments()
In JavaIn the package,
MethodHandle
Classes 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 useMethodHandle
ofasType()
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<Object> 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.