Reflection. Or Method Handles.
Reflection:
import java.lang.Reflect;
public class SomeClass {
public void someMethod() {
String a = "call";
try {
Method m = SomeClass.class.getDeclaredMethod(a);
m.setAccessible(true);
m.invoke(null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Without Reflection, using MethodHandles:
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
public class Example {
public static void main(String[] args) {
String a = "call";
try {
MethodHandle h = MethodHandles.lookup()
.findStatic(Example.class, a, MethodType.methodType(Integer.TYPE));
int result = (int) h.invokeExact();
System.out.println(result);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
@SuppressWarnings("unused")
private static int call() {
return 42;
}
}
MethodHandles are said to be faster, but they have some additional limitations, like you can only use them to call code that you can call in the current context.
This limitation works for us in this case, because call
is private, so we can call it. But if we try to do that from a different class, we will get an exception. (We can pass the result of lookup()
or findStatic()
, and others can call it for us.)
Also, the MethodHandles example works if there is a SecurityManager
.