类加载器按照层次,从顶层到底层,分为如下三种:java
(1)启动类加载器(Bootstrap ClassLoader)spa
这个类加载器负责将存放在JAVA_HOME/lib下的,或者被-Xbootclasspath参数所指定的路径中的,而且是虚拟机识别的类库加载到虚拟机内存中。启动类加载器没法被Java程序直接引用。继承
(2)扩展类加载器(Extension ClassLoader)内存
这个加载器负责加载JAVA_HOME/lib/ext目录中的,或者被java.ext.dirs系统变量所指定的路径中的全部类库,开发者能够直接使用扩展类加载器ssl
(3)应用程序类加载器(Application ClassLoader)开发
这个加载器是ClassLoader中getSystemClassLoader()方法的返回值,因此通常也称它为系统类加载器。它负责加载用户类路径(Classpath)上所指定的类库,可直接使用这个加载器,若是应用程序没有自定义本身的类加载器,通常状况下这个就是程序中默认的类加载器get
双亲委派模型:虚拟机
双亲委派模型要求除了顶层的启动类加载器外,其余的类加载器都应当有本身的父类加载器。这里类加载器之间的父子关系通常不会以继承关系来实现,而是都使用组合关系来复用父加载器的代码io
工做过程:class
若是一个类加载器收到了类加载的请求,它首先不会本身去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每个层次的类加载器都是如此,所以全部的加载请求最终都应该传递到顶层的启动类加载器中,只有当父类加载器反馈本身没法完成这个请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试本身去加载。
好处:
Java类随着它的类加载器一块儿具有了一种带有优先级的层次关系。例如类Object,它放在rt.jar中,不管哪个类加载器要加载这个类,最终都是委派给启动类加载器进行加载,所以Object类在程序的各类类加载器环境中都是同一个类,判断两个类是否相同是经过classloader.class这种方式进行的,因此哪怕是同一个class文件若是被两个classloader加载,那么他们也是不一样的类。