双亲委派模型
2025年09月21日
双亲委派模型
Java基础类库给我们提供了几种类加载器,这几种类加载器的关系如图4.5所示。

图4.5 JDK提供的几种类加载器
BootstrapClassLoader:负责加载JDK提供的基础类库,基础类库编译后的rt.jar包位于 $JAVA_HOME/lib目录下。该类加载器由C代码实现,也叫启动类加载器。
ExtClassLoader:负责加载JVM扩展类,比如内置的js引擎、xml解析器等等,这些库名通常以javax开头,它们的jar包位于 $JAVA_HOME/lib/ext目录。
AppClassLoader:应用程序加载器,负责加载classpath路径中的jar包和目录,我们编写的代码以及使用的第三方jar包通常都是由它来加载。
这几种类加载的关系并非继承关系,而是通过持有一个父加载器的引用,在外部调用loadClass方法时,先委托父加载器去加载,在父加载器抛出ClassNotFoundException异常时,再由自己去加载,如果还是加载不到类,再往上抛出ClassNotFoundException异常,这就是双亲委派模型。双亲委派的实现如代码清单4-12所示。
代码清单4-12 双亲委派的实现
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) { ...... try { if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader } if (c == null) { // If still not found, then invoke findClass in order // to find the class. long t1 = System.nanoTime(); c = findClass(name); ...... } ...... return c; } }
如果想要打破双亲委派模型,只需要在自实现的类型加载器中重写该方法,去掉try-catch部分的逻辑即可。