java中代码块执行顺序严格按源码文本顺序:静态变量默认值→父类静态块/赋值→子类静态块/赋值→父类实例默认值→父类字段赋值/构造块→父类构造体→子类实例默认值→子类字段赋值/构造块→子类构造体。

Java 中代码块执行顺序直接决定成员变量最终的值,尤其当字段显式赋值、构造代码块和构造方法混用时,稍不注意就会得到意外结果。核心在于:所有实例级初始化操作(字段赋值、构造代码块)都按源码文本顺序执行,且统一发生在构造方法体之前、super()或this()调用完成之后。
字段赋值与构造代码块按声明顺序交替执行
它们不是分两批运行,而是“谁写在前面,谁先执行”。比如:
-
private int a = 10;写在前面 → 先执行 - 紧接着是
{ b = 20; }→ 紧随其后执行 - 再后面是
private int c = getValue();→ 最后执行
如果getValue()里访问了还没走到赋值语句的d,那取到的就是d的默认值(如int为0),而不是你预期的显式值。
静态代码块影响静态变量的最终值
静态变量在“准备阶段”已被设为默认值(如0、null),而静态代码块和static字段赋值语句一起,在类初始化阶段按源码顺序执行,覆盖默认值:
-
static int x = getValue();在static { y = 5; }上面 →getValue()执行时,y还没被赋值,仍是0 - 多个
static{}块也严格从上到下执行,适合分阶段加载配置或资源 - 未被主动访问的
static字段,其赋值逻辑可能被 JVM 跳过,对应静态块也不会运行
父子类中初始化顺序形成固定链条
继承场景下,初始化不是独立进行,而是嵌套推进:
- 父类静态变量默认值 → 父类静态赋值/静态块(从上到下)
- 子类静态变量默认值 → 子类静态赋值/静态块(从上到下)
- 父类实例变量默认值 → 父类字段赋值/构造块(从上到下)→ 父类构造方法体
- 子类实例变量默认值 → 子类字段赋值/构造块(从上到下)→ 子类构造方法体
这意味着子类构造块里能安全访问父类public/protected实例变量,但不能访问private字段——作用域限制比执行顺序更刚性。
构造代码块是所有构造路径的统一入口
它被编译器自动插入到每个构造方法开头(super()之后),因此:
- 不管调用哪个构造器,构造块都会执行
- 适合提取共用初始化逻辑(如日志、状态校验、基础字段设置)
- 它能访问
this和所有实例成员,但应避免调用可能被子类重写的方法——此时子类字段尚未初始化
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











