BackendBench
Coffee

Unravel › Java concepts › JVM and performance

Java language

Method handles, VarHandle and native code

Method handles are fast, type-checked function pointers that the JIT can inline; VarHandle gives atomic and ordered access to fields; native methods and the Foreign Function & Memory API call code written in C.

Learn these first

At a glance

Mental model

Reflection is asking the receptionist to look up an extension every time.

What happens, in order
  1. 1MethodHandles.lookup().findVirtual(String.class, "length", MethodType.methodType(int.class)) returns a handle; handle.invokeExact("abc") calls it
  2. 2VarHandle vh = MethodHandles.lookup().findVarHandle(Node.class, "next", Node.class); vh.compareAndSet(node, expected, update) provides compare-and-set on any field, like atomics but on your own classes
  3. 3native marks a method implemented in C and loaded with System.loadLibrary("name") (JNI)The modern replacement is the Foreign Function and Memory API (Linker, Arena, MemorySegment), which is safer and needs no C glue code.
  4. 4sun.misc.Unsafe is the old internal back door for off-heap memory and CAS; libraries are moving away from it
Remember
Watch out
Using them in application code where an interface would doStoring a MethodHandle in a non-final field and losing the optimisationCrashing the JVM through native bugs
Example (highlighted lines explain it)
import java.lang.invoke.*;public class Handles {  private static final MethodHandle LENGTH;  static {    try { LENGTH = MethodHandles.lookup().findVirtual(String.class, "length", MethodType.methodType(int.class)); }    catch (ReflectiveOperationException e) { throw new ExceptionInInitializerError(e); }  }  static int len(String s) throws Throwable { return (int) LENGTH.invokeExact(s); }  static native void hello();}
  1. line 3 uses MethodHandle, the core of Method handles, VarHandle and native code
  2. line 5 uses MethodHandles, the core of Method handles, VarHandle and native code
  3. line 8 uses invokeExact, the core of Method handles, VarHandle and native code
Read the full explanation (about 1 min)

Method handles are fast, type-checked function pointers that the JIT can inline; VarHandle gives atomic and ordered access to fields; native methods and the Foreign Function & Memory API call code written in C.

A mental model

Reflection is asking the receptionist to look up an extension every time. A method handle is a direct-dial speed key you set up once and then press at full speed.

How it works

MethodHandles.lookup().findVirtual(String.class, "length", MethodType.methodType(int.class)) returns a handle; handle.invokeExact("abc") calls it.

VarHandle vh = MethodHandles.lookup().findVarHandle(Node.class, "next", Node.class); vh.compareAndSet(node, expected, update) provides compare-and-set on any field, like atomics but on your own classes.

native marks a method implemented in C and loaded with System.loadLibrary("name") (JNI). The modern replacement is the Foreign Function and Memory API (Linker, Arena, MemorySegment), which is safer and needs no C glue code.

sun.misc.Unsafe is the old internal back door for off-heap memory and CAS; libraries are moving away from it.

Going deeper

For application code, plain method calls and interfaces are almost always better. These tools are for frameworks, serialisers and lock-free data structures.

invokeExact needs the exact static types at the call site; a mismatch fails at run time with WrongMethodTypeException.

Native code can crash the whole JVM (segmentation fault) and bypasses bounds checks and garbage collection: treat the boundary carefully.

Under the hood

A MethodHandle is a tree of bound operations; when it is held in a static final field the JIT treats it as a constant and inlines the target, giving the speed of a direct call. Lambdas and string concatenation use invokedynamic with method handles internally.

Common mistakes

  • Using them in application code where an interface would do.
  • Storing a MethodHandle in a non-final field and losing the optimisation.
  • Crashing the JVM through native bugs.

How Unravel recognises it

When you paste code, Unravel looks for these signs of method handles, varhandle and native code. Spotting them yourself is a good habit when you read unfamiliar code:

Part of a learning path

Related concepts

Frequently asked questions

What is Method handles, VarHandle and native code?

Method handles are fast, type-checked function pointers that the JIT can inline; VarHandle gives atomic and ordered access to fields; native methods and the Foreign Function & Memory API call code written in C.

What are the most common mistakes with Method handles, VarHandle and native code?

Using them in application code where an interface would do. Storing a MethodHandle in a non-final field and losing the optimisation. Crashing the JVM through native bugs.

How can I see Method handles, VarHandle and native code in real code?

Paste your own Java into Unravel and it will point out where method handles, varhandle and native code appears, explain how it works at the detail level you choose, and draw the flow of the code around it.