Java载入器概述

来源:互联网 发布:房车工程数据 编辑:程序博客网 时间:2024/05/16 13:04

注:本文所指的系统是JVM并非OS。

当我们在命令行输入java xxx的时候,java.exe根据path中设置招到JRE,接着找到位于JRE之中的jvm.dll(正真的java虚拟机),最后载入这个动态链接库,启动java虚拟机。虚拟机一启动,会先做一些初始化的动作,比方说抓取系统参数等。一旦初始化工作完成之后,就会产生第一个类载入器,即所谓的Bootstrap Loader,Bootstrap Loader是有C++编写的(以java的观点来看,逻辑上并不存在Bootstrap Loader类的实例,所以在java程序试图打印其内容的时候,我们会看到输入为null),这个Bootstrap Loader所作的初始化工作中,除了也做一些基本的初始化工作之外,最重要的就是载入定义在sun.misc命名空间下的Launcher.java之中的ExClassLoader(因为是inner class,所以编译之后会变成Launcher$ExtClassLoader.class),并设定其Parent为null,代表其父载入器为Bootstrap Loader。然后Bootstrap Loader再要求载入定义于sun.misc命名空间下的Launcher.java之中的AppClassLoader(因为是inner class,所以编译之后会变成Launcher$AppClassLoader.class),并设定其Parent为之前产生的ExtClassLoader实例。这里请大家注意的是,Launcher$ExtClassLoader.class与Launcher$AppClassLoader.class都是由Bootstrap Loader所载入,所以Parent和由哪个类载入器载入没有关系。最后一个步骤是由AppClassLoader负责载入我们在命令行之中所输入的xxx(注意:实际上xxx很有可能由ExtClassLoader或Bootstrap Loader载入),然后开始一个java应用程序的生命周期。
 
AppClassLoader载入类时的搜索路径是从系统参数java.class.path取出的字符串所决定,而java.class.path则是由我们在执行java.exe时候,利用-cp或-classpath或CLASSPATH环境变量所决定。用下面程序测试:
public class Test{public static void main(String[] args){String s = System.getProperty("java.class.path");System.out.println(s);}}
命令行输入 java Test
如果设置了OS中环境变量CLASSPATH
输入结果是所设置的内容。
如果没有设置OS中环境变量CLASSPATH
则输入结果为 ”.” 表示当前路径。
命令行输入 java –classpath c:/test;. Test
注意这里依然要有 ”.” 否则会无法正确载入Test.java 程序无法正确执行。
这里执行结果是c:/test;.
从执行结果我们可以看出,如果我们在执行期间指定-classpath,系统设置的环境变量就失效。所以执行期间指定-classpath和系统CLASSPATH环境变量没有加成效果。
注意:这里如果用eclipse或其他IDE执行的话,结果会有差异,因为eclipse中设定了自己的classpath在项目中的.classpath文件中。
 
ExtClassLoader也有相同的情形,不过其搜索路径是参考系统参数java.ext.dirs。测试程序如下:
public class Test{public static void main(String[] args){String s = System.getProperty("java.ext.dirs");System.out.println(s);}}
执行结果是:C:/Program Files/Java/jre1.5.0_15/lib/ext
根据输出结果可以看出,系统参数java.ext.dirs的内容,会指向java.exe所选择的JRE所在位置下的/lib/ext子目录。
 
载入器Bootstrap Loader,我们可以查询系统参数sun.boot.class.path得知Bootstrap Loader用来搜索类别的路径。如下程序测试:
public class Test{public static void main(String[] args){String s = System.getProperty("sun.boot.class.path");System.out.println(s);}}
执行结果:
C:/Program Files/Java/jre1.5.0_15/lib/rt.jar;C:/Program Files/Java/jre1.5.0_15/lib/i18n.jar;C:/Program Files/Java/jre1.5.0_15/lib/sunrsasign.jar;C:/Program Files/Java/jre1.5.0_15/lib/jsse.jar;C:/Program Files/Java/jre1.5.0_15/lib/jce.jar;C:/Program Files/Java/jre1.5.0_15/lib/charsets.jar;C:/Program Files/Java/jre1.5.0_15/classes
 
总结:Bootstrap Loade
ExtClassLoader和AppClassLoader都是由Bootstrap Loade载入。但AppClassLoader的父载入器是ExtClassLoader,ExtClassLoader的父载入器是Bootstrap Loade。(其父载入器和其由哪个类载入器载入没有关系)。默认情况下:AppClassLoader搜索路径是环境变量CLASSPATH(系统参数是java.class.path)。ExtClassLoader搜索路径是java.exe所选择的JRE所在位置下的/lib/ext子目录(系统参数是java.ext.dirs)。Bootstrap Loader的搜索路径是系统指定的即JVM中指定的(搜索路径是sun.boot.class.path)。
 
以上概述了java程序载入过程,如果更深体会,会完善本文。
原创粉丝点击