java双亲委托模式classLoader

当程序在运行时,会调用一个入口函数来调用系统的相关功能,这些功能都包含在不同的class里面,有时候需要从一个class去调用其他class的方法,如果另外一个文件不存在的,则会引发系统异常。而程序在启动的时候,并不会一次性加载程序所要用的所有class文件,而是根据程序的需要,通过Java的类加载机制(ClassLoader)来动态加载某个class文件到内存当中的,只有class文件被载入到了内存之后,才能被其它class所引用。classLoad就是来用来加载class的。

java默认有三种classLoader

1. Bootstrp loader

Bootstrp加载器是用C++语言写的,它是在Java虚拟机启动后初始化的,它主要负责加载%JAVA_HOME%/jre/lib,-Xbootclasspath参数指定的路径以及%JAVA_HOME%/jre/classes中的类。
也是所有的calssLoader的parent。

2.Extension ClassLoader

称为扩展类加载器,负责加载Java的扩展类库,默认加载JAVA_HOME/jre/lib/ext/目下的所有jar。

3.App ClassLoader

称为系统类加载器,负责加载应用程序classpath目录下的所有jar和class文件。

加载机制

在Java虚拟机启动后初始化的,将会对Bootstrp loader进行初始化,然后Bootstrp loader加载Extension ClassLoader,最后再由Extension ClassLoader加载App ClassLoader,层层下来,形成了父子的关系。
当加载类时候,将会在当前层级判断类是否已经存在,如果存在则返回类的实例,如果不存在,则在父类中寻找,直到到达Bootstrp loader为止。

贴上loadClass的代码


 protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException
        {
            {
                try {
                    if (parent != null) {   //如果父类不为空委托父类加载
                        c = parent.loadClass(name, false);    
                    } else {
                        c = findBootstrapClass0(name);//如果没有父类加载器,则委托bootstrap加载器加载      } 
                    } catch (ClassNotFoundException e) {

                        c = findClass(name);//如果父类加载没有加载到,则通过findClass来加载。      } 
                    }
                    if (resolve)
                    {
                        resolveClass(c);
                    }
                    return c;
                }
    }

看到这里不禁要问,为什么要用这种方式来加载,当我们自定义classLoader时候不会触及Bootstrp loader,也就保证了Bootstrp loader中的类保持自己的样子,如果我们写一个String类,他会父类中发现了该类过后返回,也就保证了一直使用的是系统的String,不会被其他的恶意破坏。

你可能感兴趣的:(java)