1.加载(Loading)
Java虚拟机(JVM)通过类加载器根据类的全限定名通过不同渠道以二进制流的方式获取字节码信息并读取到内存中。类加载器在加载完类之后,Java虚拟机会将字节码中的信息保存到方法区中,生成一个InstanceKlass对象。同时,Java虚拟机还会在堆中生成一份与方法区中数据类似的java.lang.Class对象
类信息对象 | 存储区域 | 描述 |
---|---|---|
InstanceKlass对象 | 方法区 | 保存类的所有信息,里面还包含实现特定功能比如多态的信息 |
java.lang.Class对象 | 堆区 | 作用是在Java代码中去获取类的信息以及存储静态字段的数据(JDK8之后静态字段数据保存在堆区) |
2.连接(Linking)
子阶段 | 描述 |
---|---|
验证(Verification) | 验证字节码信息是否满足《Java虚拟机规范》,如文件格式验证、元信息验证、验证程序执行指令的语义、符号引用验证 |
准备(Preparation) | 为静态变量赋初始值(注:fianl修饰的基本数据类型,准备阶段会直接将代码中的值进行赋值) |
解析(Resolution) | 将常量池中的符号引用替换成指向内存的直接引用 |
3.初始化(Initialization)
会执行静态代码块中的代码,并为静态变量赋代码中的值(二者执行顺序取决于代码编写的顺序)。即执行字节码文件中clinit部分的字节码指令。如果类有父类,那么父类的clinit方法会先于子类的clinit方法执行
几种方式会导致类的初始化:
(1)访问一个类的静态变量或者静态方法,注意变量是final修饰的并且等号右边是常量的不会触发初始化
(2)调用Class.forName(String className)
(3)new一个该类的对象时
(4)执行main方法的当前类
4.使用(Using)
在类的初始化完成后,类的信息就准备好了,可以被程序中的其他部分使用。这包括访问类的静态字段、调用类的静态方法,或者创建类的实例等
5.卸载(Unloading)
卸载是类生命周期的最后一个阶段,当类不再被JVM中的任何对象引用时,类加载器会负责将这个类从内存中卸载掉。这个过程是垃圾回收(GC)的一部分,由JVM自动完成,不需要程序员手动干预