Week 5 — What are method handles?
Question of the Week #5
What are method handles?
7 Replies
Method handles are objects representing methods allow low-level access to them (e.g. invoking).
For creating
MethodHandle
s, one needs to obtain a MethodHandles.Lookup
which is responsible for finding the method handles first.
Then, that Lookup
object can be used for obtaining a MethodHandle
for a method in a specific class (specified by a java.lang.Class
-object), the name of the method and the signature which is represented by a MethodType
-object.
A MethodHandle
-object can be created like the following:
Similarly, it is possible to obtain VarHandle
s for fields as well as it is possible to access private members.
Assume the following class with a private
field called s
:
It is possible to access the field using VarHandles
:
Accessing private members only works if the code using method handles/creating the lookup
object has the required privileges (must have reflective access to the module it is accessing).
Consider again a class and a subclass overriding a method:
MethodHandles
can also be used to ignore runtime polymorphism using MethodHandles.Lookup#findSpecial
/ invokespecial
. This requires a Lookup
-object with access to private methods as well:
The Method Handles API is a newer, more modern, safer (e.g. it fails earlier if the types are invalid) and more powerful alternative to the Reflection API.
It allows access to bytecode instructions like
invokeinterface
/invokevirtual
/invokespecial
/invokestatic
/ via a Java API even without statically having a reference to the classes.⭐ Submission from dan1st#7327
Method handles are an conceptual construct in the Java language to provide direct, type-safe access to fields and methods. They provide the ability to dynamically invoke methods and directly access fields, allowing for more dynamic code than using traditional reflection. Method handles can also be thought of to be similar to pointers to functions in low-level languages such as C and C++.
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
public class MethodHandlesExample {
public static void main(String[] args) throws Throwable { MethodHandles.Lookup lookup = MethodHandles.lookup(); // Define method type MethodType mt = MethodType.methodType(void.class); // Access any static method MethodHandles.Lookup staticLookup = MethodHandles.publicLookup(); MethodHandle mh0 = staticLookup.findStatic(MethodHandlesExample.class, "printMessage", mt); // Access private method MethodHandle mh1 = lookup.findSpecial(MethodHandlesExample.class, "printMessage", mt, this.getClass()); // Invoke the method handle mh0.invokeExact(); mh1.invokeExact(this); } final void printMessage() { System.out.println("The message is " Hello World! ""); } }
public static void main(String[] args) throws Throwable { MethodHandles.Lookup lookup = MethodHandles.lookup(); // Define method type MethodType mt = MethodType.methodType(void.class); // Access any static method MethodHandles.Lookup staticLookup = MethodHandles.publicLookup(); MethodHandle mh0 = staticLookup.findStatic(MethodHandlesExample.class, "printMessage", mt); // Access private method MethodHandle mh1 = lookup.findSpecial(MethodHandlesExample.class, "printMessage", mt, this.getClass()); // Invoke the method handle mh0.invokeExact(); mh1.invokeExact(this); } final void printMessage() { System.out.println("The message is " Hello World! ""); } }
Submission from Arsh#9916
Method handles are a read-only meta-programming tool which works alongside the
reflection
API.
They are references to methods as well as fields which is described in the official documentation as
A method handle 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. These transformations are quite general, and include such patterns as conversion, insertion, deletion, and substitution.(https://docs.oracle.com/javase/9/docs/api/java/lang/invoke/MethodHandle.html) We will take a simple example of method handles and go through every aspect step by step. Here we can see that by creating a lookup, which acts as our way of finding the specified handle in the and, as well as the type of method we want we can scan a class for methods of the specified type with its name. After we have done this it is possible to invoke the method the handle refers to with
invokeExact
or invoke
Important differences to the reflection API are that a method handle is a direct reference or pointer to the underlying method and is a lot faster to invoke because of this. Additionally security checks are made upon creation and not invocation which also has a lot of advantages. Disadvantages are that the API is not as feature-rich as the reflection api
⭐ Submission from jade#9418
MethodHandles are the newer equivalent to the Method class from reflection. Basically a way to programmatically call another method.
Reflection was the old way of doing it, and it's still used, but methodhandles provide a ton of benefits that reflection just cant reach. MethodHandles work a lot closer to the actual jvm than reflection does, which can allow you to do some pretty funny things. Beyond that, there are other handles for constructors, fields, etc. This also means that methodhandles are a lot faster than reflection.
Submission from 0x150#3309