父类构造代码块先于子类构造方法执行,顺序为:父类构造代码块→父类构造方法→子类构造代码块→子类构造方法,由super()强制保障父类初始化完成后再执行子类逻辑。

Java中父类构造代码块和子类构造方法的执行顺序,本质是由类加载和对象创建两个阶段共同决定的,排查关键在于分清“静态初始化”和“实例初始化”两个层级,并观察super()隐式/显式调用的位置。
先看类加载时的静态部分(只执行一次)
静态代码块和静态变量初始化按类声明顺序执行,且父类优先于子类。这发生在类首次被主动使用(如new、调用静态方法等)时,与构造方法无关,但容易混淆。
- 父类静态代码块 → 子类静态代码块(仅在子类首次加载时触发)
- 静态变量赋值语句也按声明顺序穿插其中
- 可通过加日志打印 + 启动后首次new对象前观察输出确认是否属于静态阶段
再看对象创建时的实例部分(每次new都执行)
这是真正影响构造流程的核心。执行顺序固定为:父类构造代码块 → 父类构造方法 → 子类构造代码块 → 子类构造方法,前提是子类构造方法第一行是super()(默认或显式)。
- 构造代码块(非static)属于实例初始化,每次new都会执行,且在对应构造方法体之前运行
- 父类构造方法必须在子类构造方法体开始前完成,因此
super()调用必须是子类构造方法的第一条语句 - 若子类构造方法里写了
this(...),则先走本类另一个构造器,再向上追溯父类
用日志+断点快速定位执行流
最直接的排查方式是在每个可疑位置加唯一标识的日志,例如:
立即学习“Java免费学习笔记(深入)”;
- 父类静态块:`System.out.println("Parent static block");`
- 父类构造代码块:`System.out.println("Parent init block");`
- 父类构造方法:`System.out.println("Parent constructor");`
- 子类构造代码块:`System.out.println("Child init block");`
- 子类构造方法:`System.out.println("Child constructor");`
运行后按输出顺序即可清晰看到完整链条;配合IDE调试,在各处设断点,单步进入,能直观看到调用栈和执行路径。
注意几个易错点
实际排查中常因以下情况误判顺序:
- 子类构造方法里没写
super()也不报错——编译器自动插入super()到第一行,但若父类无无参构造器,会编译失败 - 构造代码块里调用了可能引发多态的方法(如重写的方法),此时实际执行的是子类版本,容易让人误以为“子类逻辑跑在父类前面”
- 匿名内部类或Lambda中引用外部类字段,可能触发外层类的实例初始化,干扰判断主线流程


















