1、加载:查找并加载类的二进制字节码
类的加载是将类的.class文件中的二进制字节码读到内存当中,此时做了两个非常主要的事情:
①将类的信息放在方法区(jdk1.8后称为元空间)(方法区里的class文件信息包括:魔数,版本号,常量池,类,父类和接口数组,字段,方法等信息)

②在堆空间创建一个代表这个类的java.lang.Class的工具 (Class工具对付反射而言很有用)
2、链接
①验证
确保被加载类的精确性(类的信息是否符合jvm规范,没有安全方面的问题等)
②准备
为类的类变量(static 静态变量)分配内存,并将其初始化为默认值(static int i = 2,初始化阶段默认值是0;final int i = 2,i是常量,准备阶段直接分配内存并且设置为目标值,以是准备阶段赋值为2),类变量随着class工具一起分配到堆中;把稳,此时并没有为实例变量分配内存空间,实例变量会随着创建实例的时候一起在堆等分配
③解析
将类中的符号引用变为直接引用。紧张针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符等7类符号引用
符号引用:用任意形式字面量表示所引用的目标
直接引用:可以指向目标的指针,偏移量或句柄等
3、初始化
为类的静态变量授予精确的初始值(static int = 2,准备阶段是0,次阶段赋值为2)
java程序对类的利用方法可分为两种 主动利用(会导致类的初始化)和被动利用
主动调用(6种)
①创建类的实例
②访问某个类或者接口的静态变量,或者对该静态变量赋值(final除外)
③调用类的静态方法
④反射(如Class.forName("com.XXXX.XXX"))
⑤初始化一个类的子类
⑥Java虚拟机启动时被标明为启动类的类
除了以上的6种情形,其他利用java类的办法都被看做对类的被动利用,不会导致类的初始化
被动利用
①当访问一个静态字段时,只有真正声明这个字段的类才会被初始化(当通过子类引用父类的静态变量,不会导致子类初始化)
②通过数组定义类引用,不会触发此类的初始化(User[] users= new User[10] )
③引用常量不会触发此类或接口的初始化。由于常量在链接阶段就已经被显示赋值了
④调用ClassLoader类的loadClass()方法加载一个类,并不是对类的主动利用,不会导致类的初始化。