java代码块执行顺序为:静态代码块→实例代码块→构造方法;静态块类加载时执行一次,实例块每次new对象时在构造方法前执行,普通块(方法内)不参与初始化流程。

Java代码块的执行顺序不是随意排列的,而是由JVM类加载和对象创建两个阶段严格决定的。搞清这个顺序,能避开很多初始化异常、空指针或值未预期的问题。
静态内容:类加载时只跑一次
静态变量赋值语句(如 static int x = 5;)和静态代码块(static { ... })在类首次被主动使用时触发,统一纳入 <clinit></clinit> 方法,按源码从上到下合并执行。注意两点:
- 准备阶段只设默认值(0、null、false),不执行任何代码;真正赋值和执行发生在初始化阶段
- final static 基本类型常量(如 public static final int MAX = 100;)是编译期常量,跳过类初始化,直接内联到调用处
- 只要访问了任一静态成员(哪怕只是读取一个字段),整个类的静态初始化逻辑就全部执行,不会“按需加载”
实例内容:每次 new 都走一遍
普通代码块({ ... })和实例变量初始化(如 String name = "Tom";)属于对象级别,在每次调用构造器前执行,顺序也是从上到下。它们与构造器的关系是:
- 先完成所有实例变量显式赋值和普通代码块(按定义顺序)
- 再进入构造器体——也就是说,构造器里看到的字段,已经是代码块处理后的值
- 普通代码块可访问任意成员(静态/实例),但静态代码块只能访问静态成员
继承场景:父类优先,层层向下
子类初始化时,JVM强制保证父类先行完成全部初始化。完整顺序分两层:
- 静态部分(仅一次):父类静态变量默认值 → 父类静态赋值/静态块(上到下)→ 子类静态变量默认值 → 子类静态赋值/静态块(上到下)
- 实例部分(每次 new):父类实例变量默认值 → 父类普通块/实例赋值(上到下)→ 父类构造器 → 子类实例变量默认值 → 子类普通块/实例赋值(上到下)→ 子类构造器
验证技巧:用日志锚定执行点
写代码时,在静态块、实例块、构造器、字段初始化方法里加 System.out.println,是最直接的验证方式。例如:
访问 Child.say() 会触发 Parent 和 Child 的静态初始化,但不会触发 Child 的实例块;而 new Child() 才会启动实例部分全流程。这种差异正是判断类是否已加载、对象是否真创建的关键依据。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











