Java 的类加载器采用了双亲委派模型,这是一种层次结构的类加载机制。在双亲委派模型中,每个类加载器都有一个父类加载器,当一个类加载器接收到加载类的请求时,它首先将这个请求委派给父类加载器进行加载。只有当父类加载器无法完成加载请求时,子类加载器才会尝试加载。
这种模型的主要目的是确保 Java 类库的安全性和一致性,避免同名类被不同的类加载器加载,防止恶意代码的注入。如果一个类被加载了,它的所有依赖类也会被加载,形成类加载器的层级结构。
以下是一个简单的 Java 代码示例,演示了双亲委派模型:
public class ClassLoaderExample {
public static void main(String[] args) {
// 获取系统类加载器(AppClassLoader)
ClassLoader appClassLoader = ClassLoader.getSystemClassLoader();
System.out.println("AppClassLoader: " + appClassLoader);
// 获取系统类加载器的父类加载器(ExtClassLoader)
ClassLoader extClassLoader = appClassLoader.getParent();
System.out.println("ExtClassLoader: " + extClassLoader);
// 获取扩展类加载器的父类加载器(BootstrapClassLoader,C++ 实现,Java 获取为 null)
ClassLoader bootstrapClassLoader = extClassLoader.getParent();
System.out.println("BootstrapClassLoader: " + bootstrapClassLoader);
// 尝试加载自定义类
try {
// 使用系统类加载器加载当前类
Class<?> customClass = appClassLoader.loadClass("ClassLoaderExample");
System.out.println("Class loaded by AppClassLoader: " + customClass);
// 尝试使用扩展类加载器加载当前类,应该抛出 ClassNotFoundException
Class<?> customClassExt = extClassLoader.loadClass("ClassLoaderExample");
} catch (ClassNotFoundException e) {
System.out.println("Class not found by ExtClassLoader");
}
}
}
在这个示例中,我们获取了系统类加载器(AppClassLoader
)、扩展类加载器(ExtClassLoader
)和引导类加载器(BootstrapClassLoader
)的实例,并通过打印输出显示了类加载器的层级结构。然后,我们尝试使用系统类加载器加载当前类,成功加载,然后尝试使用扩展类加载器加载当前类,由于类不在扩展类路径中,抛出 ClassNotFoundException
。这演示了双亲委派模型的机制。