一个类被生成的过程可以分为 加载, 连接, 初始化
在类的加载过程中:
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.初始化本类非静态成员/代码块,本类构造器
一般来说,静态成员/代码块只会在使用时初始化一次,测试同一个类时的确也是初始化一次,
注意:但在测试过程中,发现用反射调用类的静态方法或创建其实例时,再正常创建其实例,父类静态成员/代码块只会初始化一次,但子类的静态成员/代码块会初始化两次,疑惑,待解答