在Java面向对象编程中,父子类的初始化流程涉及静态代码块、构造代码块、构造方法等多个部分的执行顺序,这是理解面向对象特性的重要基础,也是实际开发和面试中的高频考察点。下面通过具体代码实战来梳理完整的执行逻辑。

Java代码块类型说明
Java中常见的代码块分为三类,不同类型的代码块在类加载和对象初始化阶段有不同的执行时机:
- 静态代码块:使用
static修饰的代码块,在类首次被加载到JVM时执行,且只执行一次,用于初始化类的静态资源。 - 构造代码块:没有修饰符的代码块,在每次创建对象时执行,且在构造方法之前执行,用于抽取多个构造方法的公共逻辑。
- 构造方法:用于初始化对象的实例属性,在构造代码块执行完成后执行。
单层父子类初始化顺序实战
首先定义父类和子类,分别在两个类中添加静态代码块、构造代码块和构造方法,通过运行结果观察执行顺序。
父类定义
public class Parent {
// 静态代码块
static {
System.out.println("父类静态代码块执行");
}
// 构造代码块
{
System.out.println("父类构造代码块执行");
}
// 构造方法
public Parent() {
System.out.println("父类无参构造方法执行");
}
}
子类定义
public class Child extends Parent {
// 静态代码块
static {
System.out.println("子类静态代码块执行");
}
// 构造代码块
{
System.out.println("子类构造代码块执行");
}
// 构造方法
public Child() {
System.out.println("子类无参构造方法执行");
}
}
测试类与运行结果
public class Test {
public static void main(String[] args) {
System.out.println("第一次创建子类对象:");
Child child1 = new Child();
System.out.println("第二次创建子类对象:");
Child child2 = new Child();
}
}
运行上述代码后,输出结果如下:
第一次创建子类对象: 父类静态代码块执行 子类静态代码块执行 父类构造代码块执行 父类无参构造方法执行 子类构造代码块执行 子类无参构造方法执行 第二次创建子类对象: 父类构造代码块执行 父类无参构造方法执行 子类构造代码块执行 子类无参构造方法执行
从结果可以总结出单层继承下的初始化顺序规则:
- 类加载阶段,优先执行父类的静态代码块,再执行子类的静态代码块,且静态代码块只在类首次加载时执行一次。
- 每次创建子类对象时,先执行父类的构造代码块和构造方法,再执行子类的构造代码块和构造方法。
- 构造代码块的执行优先级高于构造方法。
多层父子类初始化顺序扩展
如果存在多层继承,比如Child继承Parent,Parent继承GrandParent,执行顺序依然遵循同样的规则,只是层级更多。下面补充祖父类的定义验证:
public class GrandParent {
static {
System.out.println("祖父类静态代码块执行");
}
{
System.out.println("祖父类构造代码块执行");
}
public GrandParent() {
System.out.println("祖父类无参构造方法执行");
}
}
修改Parent类继承GrandParent,再次运行测试类,输出结果如下:
第一次创建子类对象: 祖父类静态代码块执行 父类静态代码块执行 子类静态代码块执行 祖父类构造代码块执行 祖父类无参构造方法执行 父类构造代码块执行 父类无参构造方法执行 子类构造代码块执行 子类无参构造方法执行
多层继承的初始化顺序可以总结为:
- 静态代码块按照继承层级从顶层父类到子类依次执行,且只执行一次。
- 每次创建对象时,构造代码块和构造方法按照继承层级从顶层父类到子类依次执行,每层先执行构造代码块再执行构造方法。
初始化流水线核心规则总结
结合上述实战案例,Java父子类初始化的完整流水线规则如下:
| 阶段 | 执行内容 | 执行次数 |
|---|---|---|
| 类加载阶段 | 从顶层父类的静态代码块开始,依次向下执行所有层级的静态代码块 | 仅一次,类首次被加载时执行 |
| 对象创建阶段 | 从顶层父类的构造代码块、构造方法开始,依次向下执行所有层级的构造代码块和构造方法,每层先执行构造代码块再执行构造方法 | 每次创建对象时执行一次 |
掌握这一规则后,在处理Java面向对象开发中的继承场景时,就可以准确预判类加载和对象初始化的执行流程,避免出现资源初始化顺序错误的问题。