Java继承中代码块执行顺序为:静态代码块(父→子,类加载时执行一次)、实例代码块(父→子,每次创建对象时在构造器前执行)、构造器(父→子)。需结合类加载与对象创建两阶段调试,日志需带类名和类型标识,并用断点验证super()调用链。

Java中继承关系下代码块执行顺序,关键在于理清静态代码块、实例代码块、构造器三类结构的触发时机和层级顺序。Debug排查时不能只看日志输出,更要结合类加载、对象创建两个阶段分别验证。
明确三类代码块的触发时机
它们不是按书写顺序执行,而是严格遵循JVM规范:
- 静态代码块:随类加载而执行,仅一次,父类先于子类(哪怕子类没被直接使用,只要被引用到就会触发其父类加载)
- 实例代码块:每次创建对象时执行,在构造器之前,父类先于子类
-
构造器:对象初始化的核心,同样遵循“先父后子”,且子类构造器第一行默认或显式调用
super()
用带标识的日志统一打印,避免混淆
在每个代码块里打印清晰、可区分的语句,包含类名、代码块类型、执行序号(可选)。例如:
class Parent {
static { System.out.println("Parent - 静态代码块"); }
{ System.out.println("Parent - 实例代码块"); }
public Parent() { System.out.println("Parent - 构造器"); }
}
<p>class Child extends Parent {
static { System.out.println("Child - 静态代码块"); }
{ System.out.println("Child - 实例代码块"); }
public Child() { System.out.println("Child - 构造器"); }
}运行new Child(),输出固定为:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
Parent - 静态代码块Child - 静态代码块
Parent - 实例代码块
Parent - 构造器
Child - 实例代码块
Child - 构造器
Debug时重点观察两个断点位置
单纯看日志容易误判,建议在IDE中设置断点辅助确认:
- 在子类构造器首行(如
super()或隐式调用处)暂停,此时父类实例代码块和构造器尚未执行完 - 在父类构造器末尾设断点,观察是否已执行完父类实例代码块 → 确认实例代码块确实在
super()调用链中提前触发
注意:静态代码块无法在构造器里打断点触发,需在类首次被主动引用时(如第一次new、Class.forName、访问静态字段)才加载执行。
常见干扰项排查清单
如果日志顺序异常,优先检查以下情况:
- 子类是否有
static字段赋值或static final常量导致父类提前加载 - 构造器中是否调用了被重写的方法(此时可能触发子类逻辑,但实例字段尚未初始化)
- 是否用了Lombok的
@RequiredArgsConstructor等注解,掩盖了显式构造器逻辑 - 是否在静态代码块里抛了异常——会导致类加载失败,后续实例化直接报
NoClassDefFoundError


















