1.加载阶段Loading
1.通过一个类的全限定名来获取定义此类的二进制字节流
2.将这个字节流的静态存储结构转化为方法区的运行时的数据结构
3.在内存中生成一个代表这个类的java.lang.Class对象
2.链接阶段Linking
1.验证 - 确保class文件的字节流包含信息符合虚拟机的规范,保证被加载类的正确性 ,比如文件格式验证,元数据验证,字节码验证,符号引用验证
2.准备 - 为类变量分配内存并且为类变量设置初始值,即零值,不包含用final修饰的static常量,这种的在编译时就会分配,这里不会为实例变量分配初始化,类变量分配在方法区中,而实例变量会分配在堆中
3.解析 - 将常量池的符号引用转化为直接引用的过程
3.初始化阶段Init
1.初始化阶段就是执行类的构造器方法<clinit>()的过程
2.此方法不需要手动定义,是java编译器自动收集类中的所有类变量的赋值动作和静态代码块的中语句合并而来
3.构造器方法中的指令按照在源文件中的顺序执行
4.<clinit>()不同与类的构造器,类的构造器是虚拟机视角下的<init>(),不显示定义就是类的默认构造方法
5.若该类具有父类,JVM会保证在子类的<clinit>()执行前,父类的<clinit>()已经执行完毕
6.虚拟机必须保证一个类的<clinit>()方法在多线程下被同步加锁,即只会在一个线程中,且只会执行一次