JVM的classLoader体系-二

JVM的classLoader体系-2

    在“JVM的classLoader体系-1”,总结了jvm的classloader一些基本的内容,肯定有很多不足的地方,还请大家指点,现在对jvm类加载机制进行一下测试:

1.建立测试文件Main.java和Test.java

Main.java:(负责打印出Main.java和Test.java的类加载器)

 

public class Main {
public static void main(String args[]){
System.out.print("Main's classLoader is ");
System.out.println(Main.class.getClassLoader());
System.out.print("Test's classLoader is ");
System.out.print(Test.class.getClassLoader());
}
}

 

 Test.java(do nothing):

 

public class Test {
}

 2.测试准备

F盘下面建立一个javasource的文件夹,并将此文件夹加到CLASSPATHvalue中,运行结果如下:

Main's classLoader is sun.misc.Launcher$AppClassLoader@19821f(Main.class的加载器)
Test's classLoader is sun.misc.Launcher$AppClassLoader@19821f(Test.class的加载器)

3.classLoader加载机制的测试:

3.1测试01-文件存放的位置

Javasource目录下:
ØMain.class
ØTest.class
Jdk\jre\ib\ext\classes目录下:
ØMain.class
ØTest.class
Jdk\jre\classes目录下:
ØMain.class
ØTest.class

3.2测试01-结果

Main's classLoader is null
Test's classLoader is null

3.3测试01-结果分析

在运行java Main的时候,由Application ClassLoader加载所需要的类,在加载的过程中,Application ClassLoader首先将加载任务委派给其父类Extended ClassLoader,Extended ClassLoader又将加载的任务委派给Bootstrap ClassLoader,由于在Bootstrap ClassLoader下面有Main.class文件,所以BootStrap ClassLoader负责类Main的加载。在Main.class中,引用了Test.class,在默认的情况下,由加载Main.class的类加载器加载Test.class,所以Test.class的类加载器也是null

3.2测试02-文件存放的位置

Javasource目录下:

ØMain.class
ØTest.class
Jdk\jre\ib\ext\classes目录下:
ØMain.class
ØTest.class
Jdk\jre\classes目录下:
ØMain.class

3.2测试02-测试结果

Main's classLoader is null

Test's classLoader is Exception in thread "main" java.lang.NoClassDefFoundError:

    Test  at Main.main(Main.java:8)

3.2测试02-测试结果分析

由于Bootstrap ClassLoader下面有Main.class,所以由Bootstrap ClassLoader负责加载Main.class,在默认的情况下,Main.class所引用的类将由Bootstrap加载,由于Bootstrap所加载的目录下的Test.class被删除了,所以出来NoClassDefFoundError的现象

3.3测试03-文件存放的位置

Javasource目录下:
ØMain.class
ØTest.class
Jdk\jre\ib\ext\classes目录下:
ØMain.class
ØTest.class
Jdk\jre\classes目录下:
ØTest.class

3.3测试03-测试结果

Main's classLoader is sun.misc.Launcher$ExtClassLoader@126b249

Test's classLoader is null

3.3测试03-测试结果分析

Main.classExtClassLoader加载,在默认的情况下,Test.class也应该由ExtClassLoader加载,ExtClassLoader首先委派其父类Bootstrap ClassLoader加载,由于Bootstrap所加载文件下有Test.class,所以由Bootstrap负责加载Test.class

3.4测试04-文件存放的位置

Javasource目录下:

ØMain.class
ØTest.class
Jdk\jre\ib\ext\classes目录下:
ØMain.class
ØTest.class
Jdk\jre\classes目录下:

3.4测试04-测试结果

 

Main's classLoader is sun.misc.Launcher$ExtClassLoader@182f0db
Test's classLoader is sun.misc.Launcher$ExtClassLoader@182f0db

3.4测试04-测试结果分析

思路如测试01

3.5测试05-文件存放的位置

Javasource目录下:

ØMain.class
ØTest.class
Jdk\jre\ib\ext\classes目录下:
ØMain.class
Jdk\jre\classes目录下:

3.5测试05-测试结果

 

Main's classLoader is sun.misc.Launcher$ExtClassLoader@126b249
Test's classLoader is Exception in thread "main" java.lang.NoClassDefFoundError:

 Test

        at Main.main(Main.java:8)

Caused by: java.lang.ClassNotFoundException: Test

        at java.net.URLClassLoader$1.run(URLClassLoader.java:202)

        at java.security.AccessController.doPrivileged(Native Method)

        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)

        at sun.misc.Launcher$ExtClassLoader.findClass(Launcher.java:229)

        at java.lang.ClassLoader.loadClass(ClassLoader.java:307)

        at java.lang.ClassLoader.loadClass(ClassLoader.java:248)

        ... 1 more

3.5测试05-测试结果分析

思路如测试02

3.6测试06-文件存放的位置

Javasource目录下:

ØMain.class
ØTest.class
Jdk\jre\ib\ext\classes目录下:
ØTest.class
Jdk\jre\classes目录下:

3.6测试06-测试结果

Main's classLoader is sun.misc.Launcher$AppClassLoader@ad3ba4
Test's classLoader is sun.misc.Launcher$ExtClassLoader@126b249

3.6测试06-测试结果分析

思路如测试03

4.总结

1.从测试结果中可以看出,类加载器在加载应用程序的class文件时,首先委托其父类进行加载,在父类加载失败的情况下,从由自己去加载。

2.在默认情况下,类A引用类B,那么类B的加载由类A的加载器或者类A加载器的父类来完成

 

 

 

 

1 楼 dingherry 2011-04-17  
很好的学习方案,by the way,LZ在看什么书呢?深入java虚拟机  吗?
2 楼 songkewei110 2011-04-17  
dingherry 写道
很好的学习方案,by the way,LZ在看什么书呢?深入java虚拟机  吗?

在看“深入java虚拟机”,看的一知半解,慢慢啃吧