NOTE
Custom Class Loader
When a custom class loader is needed, how to implement one with findClass or loadClass, an example, and a reference.
This is a historical learning note and may contain outdated or incomplete understanding.
1. When Is a Custom Class Loader Needed?
- Load class files from arbitrary paths, such as paths outside the classpath.
- Isolate class loading. This allows classes with the same name from different applications to be loaded, for example in Tomcat.
2. How to Define a Custom Class Loader
- Extend the
ClassLoaderparent class. - Override methods of the parent class.
- If using the parent-delegation mechanism, override
findClass.- Read the bytecode of the class file.
- Call the parent class’s
defineClassmethod to load the class.
- If not using the parent-delegation mechanism, override
loadClass.
- If using the parent-delegation mechanism, override
- The caller invokes the class loader’s
loadClassmethod.
3. Example
- Prepare a Java class and compile it into a class file.
public class MyClass
{
public MyClass()
{
System.out.println("hello, world!");
}
}
- Custom class loader
public class MyClassLoader extends ClassLoader
{
public static void main(String[] args) throws IllegalAccessException, InstantiationException, ClassNotFoundException
{
MyClassLoader classLoader = new MyClassLoader();
Class<?> myClass = classLoader.loadClass("MyClass");
Class<?> myClass2 = classLoader.loadClass("MyClass");
System.out.println(myClass == myClass2);// true
myClass.newInstance();// Prints hello, world!
MyClassLoader classLoader2 = new MyClassLoader();
Class<?> myClass3 = classLoader2.loadClass("MyClass");
System.out.println(myClass == myClass3);// false. A class can be uniquely identified only by class loader + package name + class name
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException
{
String path = String.format("C:\\Users\\[user]\\Desktop\\%s.class", name);
try
{
// Load the class file at the specified path and convert it into bytes
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Files.copy(Paths.get(path), outputStream);
byte[] bytes = outputStream.toByteArray();
// Call the parent class's defineClass method
return defineClass(name, bytes, 0, bytes.length);
}
catch (IOException e)
{
e.printStackTrace();
throw new ClassNotFoundException("Class file not found", e);
}
}
}
Discussion
Sign in with GitHub to comment. Discussions are stored as GitHub Issues.View on GitHub