java变量初始化分“类初始化”和“对象初始化”两阶段:前者仅一次,按声明顺序执行静态变量赋值与静态代码块;后者每次new触发,按顺序初始化实例变量、实例代码块,再执行构造方法。

Java 变量初始化与对象实例化不是线性步骤,而是分阶段、分层次、受类加载机制驱动的过程。关键在于区分「类初始化」和「对象初始化」两个独立但有依赖关系的阶段——前者只发生一次,后者每次 new 都触发。
类初始化:静态成员优先执行
当类首次被主动使用(如调用 static 方法、访问 static 字段、new 实例等),JVM 启动类初始化流程。此阶段仅执行一次,按源码顺序处理:
- 为所有静态变量分配内存并设默认值(如 int → 0,Object → null)
- 按声明顺序逐个执行静态变量赋值语句和静态代码块(二者同级,谁在前谁先执行)
- final static 编译期常量(如 static final int X = 1;)不参与运行时初始化,直接内联到调用处
对象初始化:实例成员按序填充
类初始化完成后,每次执行 new 才触发对象初始化。它发生在堆内存分配之后、构造方法执行之前,顺序固定:
- 为所有实例变量分配内存并设默认值(int → 0,引用 → null)
- 按源码中出现顺序,依次执行实例变量赋值语句和实例代码块(非 static 的 {…} 块)
- 最后才进入构造方法体——此时实例变量和代码块已全部就绪,可安全使用
继承场景下的完整链条
若有父子类继承关系,初始化严格遵循“先父后子、先静后实”原则:
- 父类静态变量 → 父类静态代码块 → 子类静态变量 → 子类静态代码块
- 父类实例变量 → 父类实例代码块 → 父类构造方法 → 子类实例变量 → 子类实例代码块 → 子类构造方法
- 注意:super() 或 this() 调用必须是构造方法第一行,它不改变上述初始化顺序,只是控制构造方法执行时机
常见误区提醒
几个容易混淆的关键点:
- “new” 不等于“初始化完成”:new 指令先分配内存并零值初始化,再触发构造逻辑;若构造中抛异常,对象虽已分配内存但未完全构建
- 静态方法里不能直接访问非静态成员:因为静态上下文启动时,实例部分根本不存在
- 局部变量无默认值:必须显式初始化才能使用,编译器强制检查,与成员变量行为完全不同
- 类加载 ≠ 类初始化:加载(读取字节码)、链接(验证/准备/解析)可能早于初始化;只有首次主动使用才会触发初始化
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











