-
Notifications
You must be signed in to change notification settings - Fork 6
Dynamic class loading and invocation
FOR MORE DETAILED EXAMPLES AND EXPLANATIONS PLEASE REFER TO JSEC
You can find JSec here.
You might find yourself in a situation where you need to load a class into the JVM at runtime.
To do this you need to use the java.lang.ClassLoader
class (of course there are many ways to load classes in the JVM but this is the most common way).
Here's some example code on setting up a class loader:
try {
ClassLoader loader = ClassLoader.getSystemClassLoader();
Class<?> klass = loader.loadClass("com.example.MyClass");
} catch (ClassNotFoundException ignored) {}
loading a class allows you to use it, for example you can load a class using it's bytes and then invoke a method you may need dynamically.
Let's say you want to invoke a method from a loaded class (optional) on the spot and you need it to be fast, in this case you can use Java's java.lang.invoke.MethodHandles
class.
Here's some example code on throwing down a setup to invoke methods, let's say you have this method you want to invoke:
public class MyClass {
public void act() {
// do something.
}
}
Now you might want to look at the Invocation page to learn how to invoke virtual methods (instance-based invocation).
try {
Class<?> klass = Class.forName("com.example.MyClass");
MethodHandles.Lookup lookup = MethodHandles.lookup();
// obtain a handle to the method
MethodHandle handle = lookup.findVirtual(
klass,
"act",
MethodType.methodType(void.class)
);
// since our method is virtual we need an instance of it
// we also should use klass.getDeclaredConstructor().newInstance()
// because klass.newInstance() is deprecated
Object instance = klass.getDeclaredConstructor().newInstance();
// invoke using instance
handle.invoke(instance);
} catch (Throwable ignored) {
ignored.printStackTrace();
}
Reflection is another concept in Java that is easier to perform compared to handle-based invocation but yields worse results as it isn't as fast as handle-based invocation.
Here's an example of how to use reflection:
try {
Class<?> klass = Class.forName("com.example.MyClass");
Method method = klass.getDeclaredMethod("act");
Object instance = klass.getDeclaredConstructor().newInstance();
// invoke using the instance
method.invoke(instance);
} catch (Throwable ignored) {
ignored.printStackTrace();
}