JVM 自带的类装载器,由 C++编写,在 JVM 运行的时候就已经存在了。java 的运行环境所需
要 的 所 有 类 库 都 由 它 来 装 载 。 ExtClassLoader 和 AppClassLoader 本 身 也 是 java 类 , 由
BootstrapClassLoader 装载到 JVM 之中。
下面用一个小例子测试三个 JVM 自带 ClassLoader 之间的关系:
例 1 JVM 自带 ClassLoader 关系的测试 (example 1)
public class ClassLoaderTest1 {
public static void main(String[] args) {
ClassLoader loader = ClassLoaderTest1.class.getClassLoader();
System.out.println("This Class is loaded by :" + loader);
System.out.println("AppClassLoader's father classLoader is :" +
loader.getParent());
System.out.println("ExtClassLoader's father classLoader is:" +
loader.getParent().getParent());
}
}
运行结果
This Class is loaded by :sun.misc.Launcher$AppClassLoader@19821f
AppClassLoader's father classLoader
is :sun.misc.Launcher$ExtClassLoader@addbf1
ExtClassLoader's father classLoader is:null
第一行表示,当前用户自定义的类由系统类装载器 AppClassLoader 进行装载。
第二行表示,系统类装载器的父加载器是扩展装载器 ExtClassLoader。
第三行表示,扩展装载器的父加载器载器为 启动类加载 bootClassLoader(由 bootStrap
classloader 不是标准的 java 类,所以在这里我们只能看到 null)。
三 ClassLoader 装载策略
从 1.2 版本开始,Java 引入了双亲委托模型,从而更好的保证了 Java 平台的安全。在此模
型下,当一个装载器被请求装载某个类时,它首先委托自己的 parent 去装载,若 parent 能装载,
则返回这个类所对应的 Class 对象,若 parent 不能装载,则由 parent 的请求者去装载。
具体顺序如图 2 所示:当 Java 中出现新的类,AppClassLoader 首先将类传递给它的父类类
装载器,也就是 ExtClassLoader,询问它是否能够装载该类。如果能,那 AppClassLoader 就不
再加载,同样 ExtClassLoader 在装载时,也会先问问它的父类装载器 BootClassloader 是否能加
载 , 如 果 能 则 由 BootClassLoader 加 载 。 当 BootClassLoader 无 法 加 载 的 时 候 , 则 返 回
ExtClassloader 一级,如果依然不能加载则再返回下面一级(AppClassLoader)。在基于类装载
器的树状的结构图中,每个类装载器有自己的父亲,类装载器在装载类时,总是先让自己的父
类装载器装载,如果父类装载器无法装载该类时,自己就会动手装载。如果自己也装载不了,
则报 Exception,class not found 的错误。