双亲委派模型(Parent Delegation Model) 是 Java 类加载器(ClassLoader)的一种工作机制,它是 Java 类加载机制的核心设计之一。理解双亲委派模型对于掌握 Java 类加载机制、解决类冲突问题以及实现自定义类加载器都非常重要。
双亲委派模型是指:当一个类加载器需要加载某个类时,它首先会委托给它的父类加载器去加载,只有在父类加载器无法加载时,才会自己尝试加载。
核心思想:
在 Java 中,类加载器是按照层次结构组织的,主要包括以下四种类加载器:
java.lang.*
、java.util.*
等),这些类通常位于 jre/lib/rt.jar
中。jre/lib/ext
目录下的类)。ClassLoader
类,实现自定义的类加载逻辑。当一个类加载器收到类加载请求时,它会按照以下步骤处理:
ClassNotFoundException
。双亲委派模型的实现主要在ClassLoader
类的 loadClass
方法中。以下是简化后的逻辑:
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
synchronized (getClassLoadingLock(name)) {
// 1. 检查是否已经加载过该类
Class<?> c = findLoadedClass(name);
if (c == null) {
try {
// 2. 委托给父类加载器
if (parent != null) {
c = parent.loadClass(name, false);
} else {
// 3. 如果父类加载器为 null,则委托给 Bootstrap ClassLoader
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// 父类加载器无法加载,忽略异常
}
// 4. 如果父类加载器无法加载,则由当前类加载器加载
if (c == null) {
c = findClass(name);
}
}
// 5. 如果需要解析,则解析该类
if (resolve) {
resolveClass(c);
}
return c;
}
}
java.lang.String
类不会被加载,因为 Bootstrap ClassLoader 已经加载了核心的 String
类。在某些场景下,需要打破双亲委派模型。例如:
如何打破双亲委派模型?
ClassLoader
的 loadClass
方法,改变类的加载顺序。DriverManager
会通过 ServiceLoader
加载所有可用的驱动类。