Java虚拟机中可以安装多个类加载器,系统默认主要有三个类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader,AppClassLoader。当然也可以自定义类加载器,自定义的加载器必须继承ClassLoader。
Java程序运行的场所是内存,当在命令行下执行:
java HelloWorld
命令的时候,JVM会将HelloWorld.class加载到内存中,并形成一个Class的对象HelloWorld.class。
其中的过程就是类加载过程:
1、寻找jre目录,寻找jvm.dll,并初始化JVM;
2、产生一个Bootstrap Loader(启动类加载器);null就代表是BootStrap类加载器,该加载器是顶级加载器,没有父类加载器
3、Bootstrap Loader自动加载Extended Loader(标准扩展类加载器),并将其父Loader设为Bootstrap Loader。
4、Bootstrap Loader自动加载AppClass Loader(系统类加载器),并将其父Loader设为Extended Loader。
5、最后由AppClass Loader加载HelloWorld类。
类加载器的委托机制
当Java虚拟机要加载一个类时,到底该派哪个类加载器去加载呢?
(1) 首先是当前线程的类加载器去加载线程中的第一个类。
(2) 如果类A中引用了类B,Java虚拟机将使用加载类A的类加载器来加载类B。
(3) 还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类。
每个类加载器加载类时,又先委托给其上级类加载器。当所有祖宗类加载器没有加载到类,回到发起者类加载器,还加载不了,则抛出ClassNotFoundException,不是再去找发起者类加载器的儿子。因为没有getChlid方法,即使有,那么当有多个儿子,找哪一个呢?
类加载器的管辖范围依次是:
BootStrap------>JRE/lib/rt.jar。启动类加载库。
ExtClassLoader———->JRE/lib/ext/*.jar。扩展类加载器。
AppClassLoader———->CLASSPATH指定的所有jar或目录。系统类加载库。
类加载有三种方式:
1、命令行启动应用时候由JVM初始化加载。
2、通过Class.forName()方法动态加载。
3、通过ClassLoader.loadClass()方法动态加载。
JVM将类加载过程分为三个步骤
1.装载:查找和导入class文件;
2.连接:
(1)检查:检查载入的class文件数据的正确性;
(2)准备:为类的静态变量分配存储空间;
(3)解析:将符号引用转换成直接引用(这一步是可选的)
3.初始化:初始化静态变量,静态代码块。
转载:http://blog.csdn.net/gjanyanlig/article/details/6818655/