java类属性初始化顺序核心是“静态优先、父类优先、声明顺序决定执行次序”:类加载时先执行父类静态变量与静态块(按源码顺序),再子类静态部分;对象创建时先父类实例变量与构造块,再父类构造方法,然后子类实例变量与构造块,最后子类构造方法。

Java类属性初始化顺序的核心是“静态优先、父类优先、声明顺序决定执行次序”。它不是随机发生的,而是由JVM在类加载和对象创建两个阶段严格控制的确定性流程。
静态成员:类加载时一次性完成
静态变量和静态代码块只在类**首次被主动使用**(如 new 实例、调用静态方法、访问非final静态字段)时触发,且仅执行一次。
- 按源码中出现的顺序依次执行:先静态变量显式赋值,再遇到静态代码块就立即执行,再下一个静态变量……
- 父类静态部分一定先于子类静态部分执行,哪怕子类先被引用——因为子类初始化会强制触发父类初始化
- 静态字段的默认值(如 int=0、Object=null)在“准备阶段”已设定;真正赋值和逻辑执行发生在“初始化阶段”
实例成员:每次new时从父到子逐层展开
每创建一个对象,JVM就在堆中分配内存后,立刻开始该对象的实例初始化,顺序固定:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 先父类:按声明顺序执行父类的实例变量赋值 + 非静态代码块(即 {} 块)
- 再父类构造方法体(此时 super() 已隐式或显式调用完毕)
- 然后子类:同样按声明顺序执行实例变量赋值 + 非静态代码块
- 最后执行子类构造方法体
注意:非静态代码块和字段初始化语句地位等同,编译后会被合并插入到每个构造方法开头(super() 之后),所以它们总在构造方法逻辑之前运行。
继承场景下的完整链条(以 new Child() 为例)
整个过程像一层层剥洋葱,确保父类状态完备后再构建子类:
- Grandparent 静态变量 → Grandparent 静态代码块
- Parent 静态变量 → Parent 静态代码块
- Child 静态变量 → Child 静态代码块
- Grandparent 实例变量 → Grandparent 非静态代码块 → Grandparent 构造方法
- Parent 实例变量 → Parent 非静态代码块 → Parent 构造方法
- Child 实例变量 → Child 非静态代码块 → Child 构造方法
容易踩坑的关键细节
这些不是理论,而是真实引发 NPE 或 ExceptionInInitializerError 的高频点:
- 在静态字段初始化中 new 当前类实例,会导致类初始化未完成就递归调用,直接抛错
- 构造块里调用可能被子类重写的方法,此时子类字段尚未初始化(仍为默认值),极易空指针
- 静态方法中访问 this 或非静态字段/方法——编译不通过,因为静态上下文与任何实例无关
- final static 字段若为编译期常量(如 public static final int X = 1),会被内联,不触发类初始化
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










