1 个解决方案
jvm 初始化一个类的过程大致如下:
-
加载
-
连接
- 验证
- 准备
- 解析
-
初始化
加载
1.取得类的二进制字节流,通过类的全限定名称(包名 + 类名);
2.把二进制字节流存储结构转化为方法区数据结构;
3.在内存生成代表这个类的 java.lang.Class
对象,这里是放在堆中;
链接
第一步:验证类的格式是否正确,主要有如下几方面的验证:
-
1.文件格式的验证;
-
2.元数据的验证;
-
3.字节码的验证;
-
4.符号引用验证;
第二步:准备
为类的静态变量(static 修饰的)分配内存(分配到方法区中),并将其初始化为默认值,如 int 初始化默认值为 0,long 初始化默认值为 0L, boolean 初始化默认值为 false.
注意:这里指的是静态变量,而非静态常量(static final 修饰的)
第三步:解析
常量池中的符号引用替换为直接引用,包括方法的调用,都是直接替换成直接应引用。
初始化
-
如果这个类还没有被加载和链接,则先加载和链接
-
如果类存在直接的父类,先初始化其父类
-
如果类中存在初始化语句,则依次执行初始化语句
-
类的构造器
: 由编译器自动收集 - static {} 语句
- static 变量
抛出一个问题?类的初始化时机?
-
new, 创建类的实例
-
反射
-
调用类的静态方法
-
初始化子类,此时需要先初始化其父类
-
访问类的静态变量,抑或给静态变量赋值
-
jvm 启动的时候的启动类