顾名思义,类装载器是用来把类 (class) 装载进 JVM 的。 JVM 规范定义了两种类型的类装载器:启动内装载器 (bootstrap) 和用户自定义装载器 (user-defined class loader) 。



JVM 的类动态装载技术能够在运行时刻动态地加载或者替换系统的某些功能模块 , 而不影响系统其他功能模块的正常运行。



装载就是寻找一个类或是一个接口的二进制形式并用该二进制形式来构造代表这个类或是这个接口的 class 对象的过程,其中类或接口的名称是给定了的。当然名称也可以通过计算得到,但是更常见的是通过搜索源代码经过编译器编译后所得到的二进制形式来构造。

  在 Java 中,类装载器把一个类装入 Java 虚拟机中,要经过 三个步骤 来完成:装载、链接和初始化,其中链接又可以分成校验、准备和解析三步,除了解析外,其它步骤是严格按照顺序完成的,各个步骤的主要工作如下:

  装载:查找和导入类或接口的二进制数据;

  链接:执行下面的校验、准备和解析步骤,其中解析步骤是可以选择的;

  校验:检查导入类或接口的二进制数据的正确性;

  准备:给类的静态变量分配并初始化存储空间;

  解析:将符号引用转成直接引用;

  初始化:激活类的静态变量的初始化 Java 代码和静态 Java 代码块。



bootstrap 是 JVM 自带的类装载器,用来装载核心类库,如 java.lang.* 等。由例 1 可以看出, java.lang.Object 是由 bootstrap 装载的。



Java 提供了抽象类 ClassLoader ,所有用户自定义类装载器都实例化自 ClassLoader 的子类。

System Class Loader 是一个特殊的用户自定义类装载器,由 JVM 的实现者提供,在编程者不特别指定装载器的情况下默认装载用户类。系统类装载器可以通过 ClassLoader.getSystemClassLoader() 方法得到。



例 1 ,测试你所使用的 JVM 的 ClassLoader

/*LoaderSample1.java*/ 


public class LoaderSample1 


{ 


 public static void main(String[] args) 


 { 


 Class c; 


 ClassLoader cl; 




 cl = ClassLoader.getSystemClassLoader(); 


 System.out.println(cl); 




 while (cl != null) 


 { 


 cl = cl.getParent(); 


 System.out.println(cl); 


 } 




 try 


 { 


 c = Class.forName(“java.lang.Object”); 


 cl = c.getClassLoader(); 


 System.out.println(“java.lang.Object’s loader is ” + cl); 




 c = Class.forName(“LoaderSample1”); 


cl = c.getClassLoader(); 


 System.out.println(“LoaderSample1’s loader is ” + cl); 


 } 


 catch (Exception e) 


 { 


 e.printStackTrace(); 


} 


 } 


} 




在我的机器上 (Sun Java 1.4.2) 的 运行结果 


sun.misc.Launcher$AppClassLoader@1a0c10f 


sun.misc.Launcher$ExtClassLoader@e2eec8 


null 


java.lang.Object's loader is null 


LoaderSample1's loader is sun.misc.Launcher$AppClassLoader@1a0c10f 




第一行表示,系统类装载器实例化自类 sun.misc.Launcher$AppClassLoader 


第二行表示,系统类装载器的 parent 实例化自类 sun.misc.Launcher$ExtClassLoader 


第三行表示,系统类装载器 parent 的 parent 为 bootstrap 


第四行表示,核心类 java.lang.Object 是由 bootstrap 装载的 


第五行表示,用户类 LoaderSample1 是由系统类装载器装载的