JVM把描述类文件的数据从.class文件加载到内存,并对数据进行校验、转换、解析和类初始化,最终形成可以被JVM使用的Java类型,这个过程称为JVM的类加载机制。
类的生命周期,是从加载到JVM内存开始,到卸载出JVM内存结束
整个生命周期包括:加载、验证、准备、解析、初始化、使用、卸载

其中从验证到解析被称为连接,从加载到初始化称为类加载。
加载:查找并加载类的二进制数据
加载阶段:
java.lang.Class对象,作为方法区这个类的各种数据的访问入口
验证:确保被加载类的正确性
文件格式验证
验证字节流是否符合Class文件格式规范
元数据验证
对字节码描述的信息进行语义分析,以保证其描述的信息符合Java语言规范要求
字节码验证
通过数据流和控制流分析,确定程序语义是否合法、符合逻辑
符号引用验证
确保解析动作能正确执行
准备:为类的静态变量分配内存,并将其初始化为默认值。
此阶段会在JVM内存中的方法区进行。
内存分配仅包括类静态变量,实例变量将会在对象实例化时随着对象一起分配到Java堆中。
这里所设置的初始值通常情况下是数据类型默认的零值(如0、0L、null、false等),引用类型为null
public class Main {
public static int i;
public static String s;
public static boolean b;
public static void main(String[] args) {
System.out.println(i); //0
System.out.println(s); //null
System.out.println(b); //false
}
}
对于同时被static和final修饰的常量,必须在声明的时候就为其显示的赋值;只被final修饰的常量,在使用前必须为其显示的赋值,系统不会为其赋予默认零值
否则IDEA会提示未初始化

解析:把类中的符号引用转换为直接引用
初始化:执行类构造器<clinit>()方法的过程
会调用java.lang.ClassLoader加载类字节码,ClassLoader会调用JVM的native方法(defineClass0/1/2)来定义一个java.lang.Class
实例
其中包括:
使用:类访问方法区内的数据结构的接口, 对象是堆区上的的数据
卸载:释放内存
JVM结束类生命周期的情况:
System.exit()方法JVM会在程序第一次注定引用类的时候加载该类,被动引用时并不会引用类加载的操作。
主动引用:
new、getstatic、putstatic、invokestatic字节码指令
new实例化对象final修饰,编译期把结果放入常量池中的静态字段除外)main()方法的主类