Java类的加载过程

来源:互联网 发布:淘宝介入了还能取消吗 编辑:程序博客网 时间:2024/06/07 09:16

1· 加载

类的加载阶段,主要是获取定义此类的二进制字节流,并将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构,最后在JAVA堆中生成

一个代表这个类的java.lang.Class对象作为方法区这些数据的访问入口。相对于类加载过程的其他阶段,加载阶段是开发期可控性最强的阶段。我们可以

通过制定不通 的类加载器,也就是Classloader来控制二进制字节流的获取方式。

2·验证

验证,准备和解析其实都属于连接阶段,而验证就是连接阶段的第一步。这一阶段只要是为了确保CLass文件的字节流中包含的信息复合当前虚拟机的要求

,并且不会危害虚拟机自身的安全。主要验证过程包括:文件格式验证,元数据验证,字节码验证以及符号引用验证。

3·准备

装备阶段正式为类变量分配内存并设置初始值。这里的初始值并不是初始化的值,而是数据类型的默认零值。这里提到的类变量是被Static修饰的变量,而

不是实例变量,关于准备阶段为类变量设置零值的唯一例外就是当这个类变量同时也被 final 修饰,那么在编译时,就会直接为这个产量赋上目标值。

4·解析

解析时虚拟机将常量池中的符号引用替换为直接引用的过程。

5·初始化

在准备阶段,变量已经赋过一次系统要求的初始值,在初始化阶段,则是根据程序员通过程序的主观计划区初始化类变量和其他资源。Java虚拟机规范规定

了有4种情况必须立即对类进行初始化(加载,验证,准备必须在此之前完成)

(1) 当使用new 关键字实例化对象时,当读取或设置一个类的静态字段(被final修饰的除外)时,以及当调用一个类的静态 方法时(比如构造方法就是

静态方法),如果类未初始化,则需先初始化。

(2)通过反射机制对类进行调用时,如果类未初始化,则需先初始化。

(3)当初始化一个类时,如果其父类未初始化,先初始化父类。

(4)用户指定的执行主类(含 main方法的那个类) 在虚拟机启动时会先被初始化。


除了上面这4种方式,所有引用类的方式都不会触发初始化,称为被动引用。如:通过子类引用父类的静态字段,不会导致子类初始化;通过数组定义来

引用类,不会触发此类的初始化;引用类的静态常量不会触发定义常量类的初始化,因为常量在编译阶段已经被放到常量池中了。


上面就是一个类加载并可以使用的整个过程,JAVA的类加载这种只有需要的时候才加载进来的做法为内存节省了很大的空间。