理论了解:html
关于类加载器的双亲委托机制基本上都据说过,面试时可能偶尔也会被问到,可是可能都是网上去找了一个理论性的答案临时了解了一下,并未对它究竟是个什么样的机制有深刻的了解,因此接下来准备深刻了解它,在了解以前固然得有理论作为支撑。java
在以前【http://www.cnblogs.com/webor2006/p/8905978.html】已经对类加载器的一个层次关系有了一个大致的了解,回顾一下:web
在父亲委托机制中,各个加载器按照父子关系造成了树形结构【注意:并不是物理上的树形结构,而是逻辑上的树形结构】,附了根类加载器以外,其他的类加载器都有且只有一个父加载器。下面来看另一张图:面试
其中loader1和loader2是自定义类加载器,所谓的类加载器的双亲委托机制是这样:假如说想要经过loader1来加载本身所编写的Sample类,而类加载器双亲委托机制并非直接由loader1直接来加载Sample类,而是先转交给loader1的父亲系统类加载器来完成,而系统类加载器又会转交给扩展类加载器去完成, 而因为扩展类加载器还有父亲根类加载器,因此说又会转到根类加载器去加载,因为它木有父加载器了,此时根类加载器就开始尝试去加载Sample类了,可是!此时根类加载器是没法加载Sample类的,为何?缘由以下:ide
也就是说此时根类加载器会加载失败,可是并非失败了就立马就返回了,而是把加载的任务又返回给它的下一级子类,也就是扩展类加载器,而扩展类加载器也加载不了自定义的类,缘由跟根类加载器相似,以下:spa
也就是不进行相应路径的配置其扩展类加载器加载Sample类确定也失败了,因而继续传给它的下一级子类系统类加载器(也叫应用加载器),而它加载的规则以下:3d
也就是通常状况下系统类加载会成功的加载我们定义的Sample类了,经过这么一个从底部往上和从顶部往下的过程其实最终加载Sample类是由系统类加载器完成的,而非是load1完成,不过会将结果返回给load1,以上的整个过程则为双亲委托机制(也叫父亲委托机制),大致能够概括为:某一个类加载器想要加载一个类,它并不是立马本身去加载该类,而是委托给它的父亲去加载,若是父亲还有父亲则继续委托,直到根类加载器了没父亲了则由它去加载,若是加载不成功则会从上到下进行委托加载,整个链上只要有一个加载器能加载成功,则最终的加载结果就是成功的,最终流程就会返回到第一次想加载类的类加载器。htm
【注意】:上面的加载机制只是在标准的hospot虚拟机上是这样的,固然JDK里采用的也是标准的这种方式,可是不并代码其它的JVM都是采用的这种双亲委托机制,了解一下。对象
再来看一下该图:blog
这个顺序恰好就是我们以前所描述的。下面再针对不一样的加载类具体描述一下其加载的特性:
另外还需了解一个概念,仅了解既可:若是有一个类加载器可以成功加载Test类,那么这个类加载器被称为定义类加载器,全部能成功返回Class对象引用的类加载器(包括定义类加载器)都被称为初始类加载器。具体理解以下:
实验:
既然已经对类加载器的双亲委托机制有了必定的了解,下面编写代码来使用一下类加载器:
在加载自定义类以前,我们先来加载系统的类,以下:
在运行以前,先来看一下getClassLoader()这个方法的说明:
编译运行:
这也是根类加载器的职责所在,再来回顾下:
好,那接下来再来加载我们本身定义的类C,以下:
而AppClassLoader的职责以下:
那我们来看一下AppClassLoader类:
位置Launcher类中,而这个类是ide根据class文件反编译出来的,由于它并非开源的,以下:
其中了解一下它的类继承关系: