类的加载连接和初始化

时间:2022-06-19 14:45:14

一个类被生成的过程可以分为 加载, 连接, 初始化

在类的加载过程中:

1.先去缓存中查询是否已经存在加载的该类,如果未加载,到2

2.根据父类加载器(如果没有父类加载器,其可能是根类加载器,到3)去查找编译后的class文件,并加载,如果未找到,到3

3.用当前的类加载器去找编译后的class文件,并加载,如果未找到,报ClassNotFoundException

4.加载生成生成Class对象,每个类都有一个Class对象,几乎所有类都是java.lang.Class对象的实例。

到2时,继续1~3步骤

一般继承ClassLoader重写findClass()方法来自定义加载策略,因为loadClass()方法中有缓存机制和调用父类加载器逻辑,

不好重写,且其会调用loadClass()方法里会调用findClass()方法。

类的连接:

验证:验证加载的类是否具有正确的内部结构,并与其他类协调一致。

准备:为一些类变量分配内存空间,并赋予其一些默认初始值,如int=0。

解析:将类的二进制数据中的符号引用替换成直接引用。

类的初始化:

    直接调用静态方法时的初始化:递归初始化父类静态成员/代码块,再初始化本类的静态成员/代码块。

    创建类的实例时的初始化:1.递归初始化父类静态成员/代码块,再初始化本类的静态成员/代码块。

                                             2.递归初始化父类非静态成员/代码块,父类构造器

                                             3.初始化本类非静态成员/代码块,本类构造器

一般来说,静态成员/代码块只会在使用时初始化一次,测试同一个类时的确也是初始化一次,

注意:但在测试过程中,发现用反射调用类的静态方法或创建其实例时,再正常创建其实例,父类静态成员/代码块只会初始化一次,但子类的静态成员/代码块会初始化两次,疑惑,待解答