类加载过程
当程序主动使用某个类时,如果该类还未被加载到内存中,系统会通过加载、连接、初始化三个步骤来对该类进行初始化,如果没有意外,JVM将会连续完成这三个步骤,所以有时也把这三个步骤统称为类加载。
(1)加载
指的是将类型的class字节码数据读入内存。
(2)连接
① 验证:校验合法性等
② 准备: 准备对应的内存(方法区)、创建Class对象,为类变量(类中的static变量)赋默认值,为静态常量 (final)赋初始化值。
③ 解析: 把字节码中的符号引用替换为对应的直接地址引用。
符号引用:
符号引用主要包含下面三类常量:
1、类和接口的全限定名(Fully Qualified Name)
2、字段的名称和描述符(Descriptor)
3、方法的名称和描述符
直接引用:
把直接替换成引用的地址
(3)初始化
initilize(类初始化) 即执行<clinit>类初始化方法,大多数情况下,类的加载就完成了类的初始化,有些情况下,会延迟类的初始化。
类的初始化执行的是<clinit>(),还方法由类变量的显示赋值代码以及静态代码块中的代码构成。
实例的初始化执行的是<init>(),实例的初始化一定晚于类的初始化
类的初始化:
(1)类的初始化就是为静态变量初始化。实际上,类初始化的过程时在调用一个<clinit>()方法,而这个方法是编译器自动生成的。编译器会将如下两部分的所有代码,按顺序合并到类初始化<clinit>()方法体中。
-
静态类成员变量的显式赋值语句
-
静态代码块中的语句
(2)每个类初始化只会进行一次,如果子类初始化时,发现父类没有初始化,那么会先初始化父类。
(3)类的初始化一定优先于实例初始化。