Java在需要使用类的时候,才会将类加载,Java的类加载是由类加载器来完成的。
在加载类时,每个类加载器会先将类的加载任务交给其parent,如果parent找不到,再由自己负责加载。即在加载类时,会以Bootstrap Loader——>Extended Loader——>System Loader的顺序来寻找类,如果都找不到,就会丢出NoClassDefFoundError。需要注意到是,Bootstrap Loader通常由C编写而成,而Extended Loader和System Loader是由Java编写而成,下面的代码中某个输出语句打印出null就是这个原因。
当在命令行模式下执行java XX.class指令后,java运行程序会尝试找到JRE安装目录,寻找jvm.dll,启动JVM并进行初始化,产生Bootstrap Loader,接着Bootstrap Loader加载Extended Loader和System Loader,并设置Extended Loader的parent为Bootstrap Loader,而System Loader定parent为Extended Loader,最后再载入XX.class。
public class classLoaderTest
{
public static void main(String[] args)
{
classLoaderTest test = new classLoaderTest();
Class<?> c = test.getClass();
ClassLoader loader = c.getClassLoader();
System.out.println(loader);
System.out.println(loader.getParent());
System.out.println(loader.getParent().getParent()); //输出为:null
System.out.println(System.getProperty("sun.boot.class.path"));
System.out.println(System.getProperty("java.ext.dirs"));
System.out.println(System.getProperty("java.class.path"));
}
}
我的机子中的运行结果如下:
sun.misc.Launcher$AppClassLoader@19821f
sun.misc.Launcher$ExtClassLoader@addbf1
null
D:\Program Files\Java\jdk1.6.0_02\jre\lib\resources.jar;D:\Program Files\Java\jdk1.6.0_02\jre\lib\rt.jar;D:\Program Files\Java\jdk1.6.0_02\jre\lib\sunrsasign.jar;D:\Program Files\Java\jdk1.6.0_02\jre\lib\jsse.jar;D:\Program Files\Java\jdk1.6.0_02\jre\lib\jce.jar;D:\Program Files\Java\jdk1.6.0_02\jre\lib\charsets.jar;D:\Program Files\Java\jdk1.6.0_02\jre\classes
D:\Program Files\Java\jdk1.6.0_02\jre\lib\ext;C:\WINDOWS\Sun\Java\lib\ext
D:\workspace\Test\bin
如果把classLoaderTest的.class文件放在其他的目录下,会有不同的运行结果。