先贴一张双亲委派机制加载图
双亲委派机制加载原理:
这里先抛开自定义类加载器。
1、首先由应用程序类加载器去加载,先检查自己是否加载过此类,如果有,直接返回。如果没有,委托给扩展类加载器加载。
2、扩展类加载器检查自己是否加载过此类,如果有,直接返回,如果没有,委托给引导类加载器进行加载。
3、引导器类加载器检查自己是否加载过此类,如果有,直接返回,没有,委托给之类进行加载
如此,直到加载成功。
贴一下类加载器的源码:
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
// First, check if the class has already been loaded
Class<?> c = findLoadedClass(name); // 检查自己是否已经加载过
if (c == null) {
long t0 = System.nanoTime();
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);
// this is the defining class loader; record the stats
sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
sun.misc.PerfCounter.getFindClasses().increment();
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
回到问题本身,为什么要子类委托给父类,而不是不直接从引导类加载器进行加载?
首先我们写的代码,基本上都是由应用程序类加载器进行加载,只有第一次加载某个类的时候,会向上委托,等下一次再使用这个类的时候,它之前已经被加载过了,就直接从应用程序类加载器获取就可以了。如果直接从引导类加载器,那么每次使用类,都得从上到下去加载,这样肯定会影响性能。
以上是个人理解,如有不对的地方,欢迎指正。