JVM有多个虚拟机,系统默认三个主要类加载器
(即BootStrap,ExtClassLoader加载jre/ext文件夹下的jar包 , AppClassLoader加载jre/lib/rt.jar里面就是所有常用java类比如io awt util等)类加载器也是普通的java类。
最根源的类加载器是用C++写的(即BootStrap),这个加载器随着JVM启动而启动,然后在调用别的用java写好的类加载器。
加载器继承图:
BootStap (jre/lib/rt.jar 常用类所在的位置 比如util io awt)
|
|
ExtClassLoader (jre/lib/ext/*.jar 扩展包所在的位置)
|
|
AppClassLoader (classpath指定的所有jar或者目录)
|
|
自定义类加载器XXXClassLoader(自定义加载指定方位的文件)
loadclass的时候,寻找确定的类加载器的顺序:
在使用类加载器加载类的时候,都要先去最祖先BootStap里面找是否加载过,如果没有向下继续,用这种方式来找真正要使用的是哪个类加载器。
使用这种方式便于集中管理,否则比如自定义类加载器A,B在自己制定范围文件夹内都找到了同一个class文件的时候,那么应该听谁的呢,就产生了混乱。
因此采用向上查询的方式来确定使用哪种类加载器,如果找到了确认使用这个类加载器,那么在加载类A的时候,发现类A引用类B那么继续使用当前线程
找到的这个类加载器继续加载类B。
如果逐层找没有找到需要的类加载器,那么返回发起者的类加载器后如果仍旧加载不了,抛出ClassNotFuound异常。