双亲委派模型的工作流程是:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把请求委托给父加载器去完成,依次向上,因此,所有的类加载请求最终都应该被传递到顶层的启动类加载器中,只有当父加载器在它的搜索范围中没有找到所需的类时,即无法完成该加载,子加载器才会尝试自己去加载该类。
双亲委派机制:
1、当 AppClassLoader加载一个class时,它首先不会自己去尝试加载这个类,而是把类加载请求委派给父类加载器ExtClassLoader去完成。
2、当 ExtClassLoader加载一个class时,它首先也不会自己去尝试加载这个类,而是把类加载请求委派给BootStrapClassLoader```去完成。
3、如果 BootStrapClassLoader加载失败(例如在 $JAVA_HOME/jre/lib里未查找到该class),会使用 ExtClassLoader来尝试加载;
4、若ExtClassLoader也加载失败,则会使用 AppClassLoader来加载,如果 AppClassLoader也加载失败,则会报出异常 ClassNotFoundException。
双亲委派模式的意义:
1、系统类防止内存中出现多份同样的字节码
2、保证java程序安全稳定运行
源码解读:
public Class<?> loadClass(String name) throws ClassNotFoundException {return loadClass(name, false);}
protected synchronized Class<?> loadClass(String name, boolean resolve)throws ClassNotFoundException {// First, check if the class has already been loaded// 首先判断该类型是否已经被加载Class c = findLoadedClass(name);if (c == null) {//如果没有被加载,就委托给父类加载或者委派给启动类加载器加载try {if (parent != null) {//如果存在父类加载器,就委派给父类加载器加载c = parent.loadClass(name, false);} else {//如果不存在父类加载器,就检查是否是由启动类加载器加载的类,//通过调用本地方法native Class findBootstrapClass(String name)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.// 如果父类加载器和启动类加载器都不能完成加载任务,才调用自身的加载功能c = findClass(name);}}if (resolve) {resolveClass(c);}return c;}