首页 > 代码库 > java类加载器
java类加载器
类的加载过程
JVM将类加载过程分为三个步骤
装载,连接,初始化,连接又分为三个步骤如下:
JVM将类加载过程分为三个步骤:装载(Load),链接(Link)和初始化(Initialize)链接又分为三个步骤,如下图所示:
1)装载:查找并加载类的二进制数据;
2)链接:
- 验证:确保被加载类的正确性;
- 准备:为类的静态变量分配内存,并将其初始化为默认值;
- 解析:把类中的符号引用转换为直接引用;
3)初始化:为类的静态变量赋予正确的初始值;
那为什么我要有验证这一步骤呢?首先如果由编译器生成的class文件,它肯定是符合JVM字节码格式的,但是万一有高手自己写一个class文件,让JVM加载并运行,用于恶意用途,就不妙了,因此这个class文件要先过验证这一关,不符合的话不会让它继续执行的,也是为了安全考虑吧。
准备阶段和初始化阶段看似有点牟盾,其实是不牟盾的,如果类中有语句:private static int a = 10,它的执行过程是这样的,首先字节码文件被加载到内存后,先进行链接的验证这一步骤,验证通过后准备阶段,给a分配内存,因为变量a是static的,所以此时a等于int类型的默认初始值0,即a=0,然后到解析(后面在说),到初始化这一步骤时,才把a的真正的值10赋给a,此时a=10。
类的初始化
类什么时候才被初始化:
- 1)创建类的实例,也就是new一个对象
- 2)访问某个类或接口的静态变量,或者对该静态变量赋值
- 3)调用类的静态方法
- 4)反射(Class.forName("com.lyj.load"))
- 5)初始化一个类的子类(会首先初始化子类的父类)
- 6)JVM启动时标明的启动类,即文件名和类名相同的那个类
只有这6中情况才会导致类的类的初始化。
类的加载
启动JVM的时候,可以使用三个类加载器:引导(bootstarp)类加载器,扩展(extensions)类加载器,应用程序(application)类加载器。
引导类加载器:仅仅负责加载核心的Java库,比如位于<JAVA_HOME>/jre/lib目录下的vm.jar,core.jar。这个类加载器,是JVM核心部分,是用native代码写成的。
扩展类加载器:负责加载扩展路径下的代码,一般位于<JAVA_HOME>/jre/lib/ext或者通过java.ext.dirs这个系统属性指定的路径下的代码。这个类加载器是由sun.misc.Launcher$ExtClassLoader实现的。
应用类加载器: 一般来说,Java应用的类都是由它来完成加载的。可以通过 ClassLoader.getSystemClassLoader()来获取它。
如果应用程序类加载器需要加载一个类,它首先委托扩展类加载器,扩展类加载器再委托引导类加载器。如果父类加载器不能加载类,子类加载器就回在自己的库中查找这个类。基于这个特性,类加载器只负责它的祖先无法加载的类。
小结:
类加载器是java的一个创新,基本上所有的类加载器都是用java.ClassLoaderler加载的一个实例。基本目的是帮助我们理解对象的实例化过程以及对象的调用。
java类加载器