现在的位置: 首页 > 综合 > 正文

类装载器ClassLoader的工作机制

2013年12月10日 ⁄ 综合 ⁄ 共 1537字 ⁄ 字号 评论关闭

类装载器就是寻找类的字节码文件并构造出类在JVM内部表示的对象组件。在JAVA中,类装载器把一个类装入JVM中,要经过以下几个步骤:

1.装载:查找和导入Classwenjian 

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

(a) 校验:检查载入Class文件数据的正确性

(b)准备:给类的静态变量分配存储空间

(c)解析:将符号引用转成直接引用

3.初始化:将符号引用转成直接引用

类装载工作由ClassLoader及其子类负责,ClassLoader是一个重要的Java运行时系统组件,它负责在运行时查找和装入Class字节码文件。JVM在运行时会产生三个ClasssLoader:根装载器、ExtClassLoader(扩展类装载器)和AppClassLoader(系统类装载器)。其中,根装载器不是ClassLoader的子类,它使用C++ 编写,因此我们在Java中看不到它,根装载器负责装载JRE的核心类库,如JRE的核心类库,如JRE目标下的rt.jar、charsets.jar等。ExtClassLoader和AppClassLoader都是ClassLoader的子类。其中ExtClassLoader负责装载JRE扩展目录ext中的JAR类包;AppClassLoader负责装载ClassPath路径下的类包、

这三个类装载器之间存在父子 层级关系,即根装载器是ExtClassLoader的父装载器,ExtClassLoader是AppClassLoader的父装载器。默认情况下,使用AppClassLoader装载应用程序的类,我们可以做一个实验:

public class ClassLoaderTest {
	public static void main(String[] args) {
		ClassLoader loader = Thread.currentThread().getContextClassLoader();
		System.out.println("current loader:" + loader);
		System.out.println("parent loader:" + loader.getParent());
		System.out.println("grandparent loader:" + loader.getParent().getParent());
	}
}

运行以上代码,在控制台上将打出以下信息:

current loader:sun.misc.Launcher$AppClassLoader@61e63e3d
parent loader:sun.misc.Launcher$ExtClassLoader@53004901
grandparent loader:null

通过以上的输出信息,我们知道当前的ClassLoader是AppClassLoader,父ClassLoader是ExtClassLoader,祖父ClassLoader是根装载器,因为在Java中无法获得它的句柄,所以直接返回null。

JVM装载类时使用“全盘负责委托机制”,“全盘负责”是指当一个ClassLoader装载一个类时,除非显示地使用另一个ClassLoader,该类所依赖及使用的类也由这个CLassLoader载入;“委托机制”是指先委托父装载器寻找目标类,只有在找不到的情况下才从自己的类路径中查找并装载目标类。这一点是从安全角度考虑的,试想如果有人编写了一个恶意的基础类(如java.lang.String)并装载到JVM中将会引起多么可怕的后果。但是由于有了“全盘负责委托机制”,java.lang.String永远是由根装载器来装载的,这样就避免了上述事件的安全。

抱歉!评论已关闭.