前言:本博客内容由张孝祥Java高新技术整理而来
java虚拟机中可以安装多个类加载器,系统默认三个主要的类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader,AppClassLoader。
类加载器也是java类,因为其他事java类加载器本身也要被类加载器加载,显然必须有第一个类加载器不是java类,这正是BootStrap。
java虚拟机中的所有雷庄在其采用具有父子关系的树形结构进行组织,在实例化每个类装载器对象时,需要为其制定一个父级类装载器或者默认采用系统类装载器为其父级类加载。
首先是一个实例,这个例子将本身这个类的加载器名称和其父类加载器名称打印了出来
package com.dao.chu.movie;
public class ClassLoaderTest {
public static void main(String[] args) {
ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();
while (null != classLoader) {
System.out.println(classLoader.getClass().getName());
classLoader = classLoader.getParent();
}
}
}
输出结果:
sun.misc.Launcher$AppClassLoader
sun.misc.Launcher$ExtClassLoader
其中根加载器为null也就是BootStrap
下面是类加载器之间的父子关系和管辖范围图:
下面我们将ClassLoaderTest这个类导出一个jar包到jre的ext目录下
注意:如果直接导出有权限错误问题,可先导出到其他目录,在拷贝到jre下
我们再次运行刚才的代码
运行结果:
sun.misc.Launcher$ExtClassLoader
只有ExtClassLoader加载了,证明了ExtClassLoader的管辖范围,并且类加载是先从父加载器加载,加载不到才会到子加载器加载。
类加载器的委托机制
首先当前线程的类加载器去加载线程中的第一个类。
如果类A中引用了类B,java虚拟机将使用加载类A的类加载器加载类B。还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类。
每个类加载器加载类时,又先委托给其上级类加载器。
当所有祖宗类加载器没有加载到泪,回到发起者加载器,还加载不到则抛出ClassNotFoundException,而不是再去找发起者的儿子类。