向上委托:指现在自己的加载器,判断是有自己已经加载了,如果加载了直接返回class对象,没有的话,向上委托给父加载器
每个加载器都有自己的内存空间,先看在不在,不在的话再向上加载,父类加载也不再的话再像下也就是子类加载器加载
加载流程:
1、当某个类加载器(例如自定义加载)要加载类时,它先把该类加载请求委派给父类加载器去完成,而不会自己去加载该类
2、每层的类加载器都是如何,因此所有的加载请求最终都应该传送顶层的跟类加载器
3、只有当父类加载反馈自己无法完成该加载请求(它的搜索范围中没有找到所需要的类)时,子加载器才会自己去加载
具体代码在
java.lang.ClassLoader#loadClass(java.lang.String, boolean)
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) {
//没有被加载过,调用父类加载器的loadclass
c = parent.loadClass(name, false);
} else {
//如果父类加载器为空,采用boostrap启动类加载器作为父加载器
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
if (c == null) {
//在父类加载器无法加载时,再调用本身的findclass方法进行类加载,去磁盘代码路径去查找
// 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;
}
}