代码验证
执行结果:
根据我们使用的代码验证发现,如果一个类继承了莫个类,进行子类的初始化阶段,其执行顺序如下:父类的类加载阶段->子类类加载阶段->父类初始化->子类初始化。我们将在本文中介绍其原理。
对象的初始化阶段
对象的初始化阶段包括以下几个步骤:
类加载阶段->分配内存->初始化默认值->设置对象头->执行实例初始化
类加载阶段:判断该类是否进行了类加载,如果没有执行类的类加载
分配内存:为对象分配内存空间
初始化默认值:初始化对象属性的默认值,例如int类型的成员变量初始化默认值为0
设置对象头:设置对象的对象头,对象头的信息包括类信息、元数据以及迭代年龄等
实例初始化:执行成员变量的显式赋值和实例代码块,然后执行构造方法
类加载阶段
类加载阶段就是负责将编译后的字节码文件加载到JVM中,然后由虚拟机解释执行。
类加载阶段包括加载、连接、初始化,连接包括验证、准备、解析。
加载:通过类加载器加载这个类,将其转换为方法区的运行时数据结构,并且在内存中生成一个Class对象(反射的原理)
验证:验证加载进的字节码文件,防止其危害虚拟机,包括文件格式验证、元数据验证等
准备:为静态变量分配内存,并且初始化默认值
解析:将一个类引用另一个类的符号引用转换为直接引用
初始化:执行静态代码块以及静态变量的显示赋值
代码执行逻辑
当调用一个类的初始化时,首先判断该类有没有进行类加载阶段,该类继承了父类,父类也没有进行类加载阶段,因此父类先进行类加载阶段,在类加载阶段的初始化阶段执行了静态代码块的逻辑以及静态变量的显示赋值,在父类和子类都进行类加载阶段后,执行子类的初始化方法,而在其构造方法中,会被中转到父类的构造方法,因此先执行父类的实例代码块和实例成员的显式赋值,然后在执行父类的构造方法,最后调用子类的实例代码块、显式赋值以及子类的构造方法。