Metaprogramming

metaprogramming5ReflectionVsHandles

Path
pkg17metaprogramming/metaprogramming5ReflectionVsHandles.java
Package
pkg17metaprogramming
Study order
5
Run
Single-file source launch
Command
java pkg17metaprogramming/metaprogramming5ReflectionVsHandles.java

There is no in-browser runner. This is the file from the curriculum, unchanged.

pkg17metaprogramming/metaprogramming5ReflectionVsHandles.java
1package pkg17metaprogramming;2 3import java.lang.reflect.Method;4import java.lang.invoke.MethodHandle;5import java.lang.invoke.MethodHandles;6import java.lang.invoke.MethodType;7 8/*9 * metaprogramming5ReflectionVsHandles.java10 * ------------------------------------------11 * Reflection vs MethodHandles: when to use each.12 *13 * DEFINITION:14 *   Reflection (java.lang.reflect) is flexible but slower and less type-safe.15 *   MethodHandles are the JVM's preferred dynamic invocation path — faster and16 *   enforce type signatures at lookup time.17 *18 * KEY POINTS:19 *   - Reflection: Method.invoke() — easy, works everywhere, slower.20 *   - MethodHandles: invoke()/invokeExact() — faster, used by lambdas.21 *   - Security: modules can block deep reflection on non-exported packages.22 *   - For frameworks at scale: prefer MethodHandles + bytecode (ASM/Byte Buddy).23 */24public class metaprogramming5ReflectionVsHandles {25 26    static class Target {27        String shout(String msg) { return msg.toUpperCase(); }28    }29 30    public static void main(String[] args) throws Throwable {31        Target t = new Target();32        String input = "hello";33 34        // Reflection35        long rStart = System.nanoTime();36        Method m = Target.class.getDeclaredMethod("shout", String.class);37        m.setAccessible(true);38        for (int i = 0; i < 100_000; i++) m.invoke(t, input);39        long rNanos = System.nanoTime() - rStart;40 41        // MethodHandle42        MethodHandle mh = MethodHandles.lookup().findVirtual(43                Target.class, "shout", MethodType.methodType(String.class, String.class));44        long hStart = System.nanoTime();45        for (int i = 0; i < 100_000; i++) mh.invoke(t, input);46        long hNanos = System.nanoTime() - hStart;47 48        System.out.println("Reflection 100k invokes: " + (rNanos / 1_000_000) + " ms");49        System.out.println("MethodHandle 100k invokes: " + (hNanos / 1_000_000) + " ms");50        System.out.println("(MethodHandle often faster; direct calls are fastest of all)");51    }52}