类的初始化过程
类加载的时机
- 加载
加载与连接阶段的验证动作是交叉进行的
-
连接
- 验证
- 文件格式验证。是否符合Class文件格式的规范
- 语义分析。父类,抽象类,接口等。
- 字节码验证
- 符号引用验证
-
准备
正式为类变量分配内存并设置类变量初始值的阶段
1
2
3
public static int value=123;
//final的话 准备阶段既123;
//非常量的 static 则准备阶段是0;<clinit>类构造方法执行才会变成123
-
解析
可选的,loadClass第二个参数来判定是否需要解释。这里的解释是根据勒种的符号引用查找相应的实体,在把符号引用替换成一个直接引用的过程。
- 验证
- 初始化
- 使用
- 卸载
类什么时候才被初始化
-
只有这6中情况才会导致类的类的初始化
- 创建类的实例,也就是new一个对象
- 访问某个类或接口的静态变量,或者对该静态变量赋值
- 调用类的静态方法
- 反射(Class.forName(“com.lyj.load”))
- 初始化一个类的子类(会首先初始化子类的父类)
- JVM启动时标明的启动类,即文件名和类名相同的那个类
-
所有引用类的方法都不会触发初始化,称为被动引用。
类引用父类的静态字段,不会导致该类被初始化
-
类的初始化步骤:
- 如果这个类还没有被加载和链接,那先进行加载和链接
- 假如这个类存在直接父类,并且这个类还没有被初始化(注意:在一个类加载器中,类只能初始化一次),那就初始化直接的父类(不适用于接口)
- 加入类中存在初始化语句(如static变量和static块),那就依次执行这些初始化语句。