java继承中构造方法执行顺序本质是jvm强制的“父类先就绪、子类后构建”链条:静态部分(父类静态变量→父类静态块→子类静态变量→子类静态块)仅首次加载类时执行一次;实例部分(父类默认初始化→父类显式初始化→父类构造器→子类默认初始化→子类显式初始化→子类构造器)每次new都完整执行。

Java 继承关系中构造方法的执行顺序,本质是“父类先就绪、子类后构建”的强制链条,不是靠记忆口诀,而是由 JVM 在对象创建时严格按阶段推进的。关键要分清两个独立阶段:类加载时的静态初始化(只一次),和每次 new 时的实例初始化(每次都走全链)。
静态部分:类首次加载时执行,仅一次
这部分与构造方法无关,但常被误认为是“构造过程”。它发生在第一次主动使用类(比如 new、调用静态方法、访问静态字段)时:
- 父类静态变量赋值(按源码声明顺序)
- 父类静态代码块(紧随其后,多个则按书写顺序)
- 子类静态变量赋值
- 子类静态代码块
之后无论 new 多少次对象,这些都不会再执行。例如先 new Parent 再 new Child,父类静态块已在第一次完成,子类静态块只在 Child 首次被加载时触发。
实例部分:每次 new 都完整执行,自顶向下逐层展开
这才是真正决定构造方法何时运行的核心流程。JVM 从 Object 开始,一层层向下初始化,顺序固定且不可跳过:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 父类成员变量默认初始化(如 int → 0,Object → null)
- 父类显式初始化(成员变量赋值语句 + 非静态代码块,按源码顺序)
- 父类构造方法体(此时 super() 已隐式或显式完成,且必须是第一条语句)
- 子类成员变量默认初始化
- 子类显式初始化(成员变量赋值 + 非静态代码块)
- 子类构造方法体
注意:编译器会把非静态代码块和成员变量赋值“插入”到对应构造方法 super() 调用之后、方法体之前,所以它们总在构造方法体代码前执行。
怎么快速验证和排查执行顺序
最可靠的方式不是背顺序,而是动手观察:
- 在父类静态块、父类非静态块、父类构造方法、子类非静态块、子类构造方法里,分别加带标识的日志,如 "Parent static"、"Parent init"、"Parent ctor" 等
- main 中连续 new 两次子类对象,看输出:第一次出现全部日志;第二次只出现实例相关部分(静态部分不再打印)
- 配合 IDE 断点,在每个日志行设断点,单步进入,能清晰看到调用栈从 Object → 父类构造 → 子类构造的推进路径
容易踩坑的关键细节
这些地方看似微小,却常导致 NullPointerException 或值为 0/false 的诡异问题:
- 父类构造方法中调用被子类重写的方法 → 此时子类成员变量尚未显式初始化,拿到的是默认值(如 int 字段为 0)
- 子类构造方法没写 super(),编译器自动补 super(),但若父类没有无参构造,直接编译失败
- 写了 this() 调用本类其他构造器 → 那个构造器仍需满足 super() 在第一行,最终还是会追溯到父类构造
- 静态代码块里不能用 this 或实例变量(无对象上下文),而实例代码块可以安全访问 this 和所有成员
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










