顾名思义,类装载器是用来把类
(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
是由系统类装载器装载的