类的加载过程分为 加载 链接 初始化以下分别描述这三个过程
1. 加载
这个过程是将编译成功后的.class文件 以一个二进制的字节流加载到jvm中,这个字节流会进入到方法区,转换为一个数据结构。同时生成一个.class对象
2. 链接
2.1 验证
这个验证阶段主要是看看,这个字节流是否符合Java虚拟机规范,以免破坏虚拟机。比如这个.class文件是以CAFEBABY开头的
2.2 准备
这个阶段主要是进行类变量的初始化过程,例如,将一个静态的int型变量赋值为0
2.3 解析
这个阶段主要是将.class文件的符号引用转为直接引用的过程
3. 初始化
这个阶段是对于类变量的实际赋值阶段,例如执行静态代码块,执行静态变量的赋值操作。注意,这两者按照顺序执行。相当于执行了方法 0 bipush 20 2 putstatic #7 <org/example/jvmlearning/learning01/JiaZai.a : I> 5 bipush 10 7 putstatic #7 <org/example/jvmlearning/learning01/JiaZai.a : I> 10 return 为啥可以不在意这个定义顺序的先后呢?原因是在准备阶段已经有这个类变量了,后面的只是按照顺序执行赋值操作而已。注意一下,这个加载过程,是一个单线程进行的操作,一个线程进来加载就行了。如果一个类还没有加载成功,其他的线程加载的时候,会进入阻塞阶段
package org.example.jvmlearning.learning01;
public class JiaZai {
public static void main(String[] args) {
OOO ooo = new OOO();
new Thread(){
@Override
public void run() {
new OOO();
}
}.start();
}
}
class OOO{
static int a = 20;
static {
if(true){
while(true){
}
}
}
}
这个子线程会阻塞住,因为主线程没有加载完。