1. 加载
1. 通过一个类的全限定名获取定义此类的二进制字节流
2. 将这个字节流所代表的的静态存储结构转化为方法区的数据结构
3. 在内存中生成一个代表这个类的class对象,作为方法区这个类的各种数据访问入口
2. 验证
1. 验证class文件的字节流中包含的信息符合《java虚拟机规范》的全部约束,保证这些信息被当做代码运行时不会危害虚拟机本身
2. 文件格式验证。元数据验证。字节码验证。符号引用验证
3. 准备
1. 准备阶段是为类的定义的静态变量分配内存并设置类静态变量初始值的阶段
public static val = 123
在此阶段 val的初始值 是0 而不是123,123 时在初始化阶段才会被执行
4. 解析
1. 解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程
5. 初始化
1. 初始化阶段就是执行类构造器<clinit>()方法的过程,此构造器不是我们在代码中写的构造方法。
2. <clinit>()是由编译器自动收集类中所由类静态变量的赋值动作和静态代码块中的语句合并产生的。收集顺序是由语句在源文件文件中出现的顺序决定。
3. 虚拟机会保证子类的<clinit>()方法执行前。父类的<clinit>()方法已经执行完毕。
4. 触发初始化的动作
1. 遇到new getstatic putstatic 或 invokestatic 这四个字节码指令时,如果类型没有进行过初始化过程值需要触发初始化阶段
1. 使用new 关键字实例化对象时
2.读取或设置 类静态变量时(被final 修饰,已在编译期间把结果放入常量池的静态字段除外)时
3. 调用一个类的静态方法时
2. 对类型进行反射调用的时候,如果类没有初始化触发初始化阶段
3. 当初始化子类时发现父类还没有初始化则调用父类初始化
4. 当虚拟机启动时 主类(main)会被初始化
5. 当时用jdk1.7中动态语言支持时
5. 只有首次 主动引用才会触发类的初始化
6. 使用
1. 使用类静态属性或方法或者创建对象
7. 销毁
1. 将类从内存中销毁,从此不能再使用该类创建对象
- 验证,准备,解析 也是连接阶段
- 加载阶段和 连接阶段的部分动作是交叉进行,加载尚未结束,连接可能已经在进行。但加载一定是先开始的