子类实例化时父类被完整独立初始化:1.静态部分父类先于子类执行且仅一次;2.实例部分每次new都按父类实例块→父构造器→子类实例块→子构造器顺序执行。

子类实例化时,父类对象不是“被复制”或“被引用”,而是被完整、独立地初始化一次——这个过程由 JVM 严格控制,且不可跳过、不可绕行。
静态部分:父类先加载,只执行一次
当第一次执行 new Child() 时,JVM 发现 Child 类尚未初始化,就会沿继承链向上检查并强制初始化其父类(如 Parent):
- 先为
Parent分配类元数据空间,按源码顺序执行所有静态变量显式赋值(如static int x = 10;)和静态代码块(static {}) - 父类静态初始化完成后,才轮到
Child的静态变量和静态块 - 该过程在整个 JVM 生命周期中仅发生一次;后续再 new 其他子类对象或调用静态方法,不会再重复执行
实例部分:每次 new 都从父类开始逐层构建
真正创建对象时,内存分配和字段初始化严格按“父进子出”流程推进:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- JVM 为整个对象(含父类和子类字段)一次性分配内存,并将所有字段设为默认值(
0、null、false) - 进入
Parent初始化阶段:按源码顺序执行实例变量赋值(如String name = "A";)和实例代码块({ ... }),再执行Parent构造函数体 -
Parent构造函数执行完毕并返回后,才开始Child的实例变量赋值、实例块、构造函数体 - 注意:
super()是隐式或显式的首条语句,它不是“调用父类构造器”的可选项,而是触发上述父类初始化流程的开关
关键细节:字段与方法的行为不同
初始化过程中,字段访问和方法调用遵循完全不同的绑定规则:
立即学习“Java免费学习笔记(深入)”;
- 字段是静态绑定:看变量声明类型。例如
Parent p = new Child(); p.name访问的是Parent中定义的name - 方法是动态绑定:看实际对象类型。即使在
Parent构造器中调用print(),若Child重写了它,执行的仍是Child.print() - 陷阱常见于父类构造器中调用可重写方法:此时
Child的实例字段尚未赋值(仍为默认值),但子类方法已可运行,容易导致空指针或逻辑错误
如何验证初始化顺序
最直接的方式是在各处添加日志输出,例如:
- 每个静态块里写
System.out.println("Parent static block"); - 每个实例块和构造器开头加对应日志
- 运行
new Child(),观察输出顺序是否符合“父静→子静→父实→父构→子实→子构”

















