虚拟机类加载过程

类加载全过程 : 加载 --> 验证 --> 准备 --> 解析 --> 初始化

1、加载 (一般从war中读取)

 (1)、通过类的限定名获取此类的二进制字节流

 (2)、将二进制字节流的静态存储结构转化为方法区的运行时数据结构

 (3)、在Java堆生成这个类的对象,作为方法区的数据访问入口

2.验证 (确保class文件的字节流包含的信息符合虚拟机的要求)

(1)文件格式验证:包括开头字符是否合规、 版本号是否符合、常量值是否标准、class文件信息

(2)元数据验证:主要是检验类的字段、方法与父类是否有冲突,对数据类型进行语义检验

(3)字节码检验:主要是对方法体进行检验,保证方法在运行时不会出现错误

        a.保证栈中数据类型和程序指令序列配合工作

       b.保证程序指令跳转不会出错

       c.保证方法体中class的类型转换是有效的

(4)符号引用验证 :对类自身以外的信息校验,确保解析动作能正常进行,若出现错误,就会抛出java.lang.IncompatibleClassChangeError异常的子类,如java.lang.IllegalAccessError、java.lang.NoSuchFieldError、java.lang.NoSuchMethodError等

       a.符号引用中通过字符串描述的全限定名是否能找到对应的类

       b.在指定类中的是否存在符合方法的字段描述

       c.符号引用的类,方法,字段的访问性(private,public,protected,default)是否能被当前类访问

3、准备(这个阶段是在方法区中为类变量<仅包含类变量,就是被static修饰的变量,不包含实例变量,实例变量会和实例对象一起被分配在堆上>分配内存空间和初始值,一般情况下初始值都为0,除了被final修饰的常量值)

4、解析 (主要是虚拟机讲常量池中的符号引用转换为直接引用,针对类或接口、字段、方法、借口方法四类符号引用进行,分别对应常量池中的CONSTANT_Class_info、CONSTANT_Fieldref_info、CONSTANT_Methodref_info、CONSTANT_InterfaceMethodref_info)

5、初始化 (根据Java程序代码初始化变量和其他资源,这个阶段是执行<clinint>()方法)   

猜你喜欢

转载自blog.csdn.net/qq_32128693/article/details/82964615