静态代码块最先执行且仅一次,在类初始化阶段;实例代码块每次创建对象时执行,位于super()之后、构造器体之前;局部代码块仅在方法执行流到达时运行。

静态代码块最先执行,且只执行一次,在类初始化阶段;实例代码块不参与类加载,每次创建对象时才执行,严格位于构造器体之前;局部代码块完全不涉及类加载,只在方法被调用、执行流到达时运行。
静态代码块:类初始化阶段唯一触发
它不是在类被加载(Loading)时运行,而是在JVM执行「类初始化」(Initialization)阶段才执行,且仅一次。这个阶段由首次主动使用触发,例如:
- new 某个类的实例
- 调用该类的 public static 方法
- 访问非编译期常量的 public static 字段(如 public static int PORT = 8080; 会触发,但 public static final int PORT = 8080; 不会)
- 反射调用 Class.forName("X")
多个静态代码块按源码从上到下顺序执行。若其中抛出未捕获异常,类进入“初始化失败”状态,后续所有对该类的主动使用都会直接抛出 ExceptionInInitializerError。
实例代码块:对象创建时执行,与类加载无关
它属于对象初始化的一部分,不参与类加载流程。每次调用构造器前自动执行,准确位置是:super() 调用完成之后、本构造器方法体开始之前。
- 会被编译器隐式“复制”到每个构造器开头
- 父类和子类中,它总在对应构造器之前执行,但晚于所有静态代码块
- 可安全赋值实例字段、调用实例方法(前提是不依赖未初始化状态)
局部代码块:纯语法结构,不属生命周期机制
它只是方法体内的一对大括号,既不参与类加载,也不参与对象初始化,仅用于控制变量作用域或提前释放资源。
- 执行时机完全取决于所在方法是否被调用、执行流是否到达该位置
- 哪怕类从未被初始化(如从未 new、未调用 static 方法),只要方法被执行到此处,它就运行
- 与静态块、实例块没有固定先后关系——它只是普通语句序列中的一段
一句话总结绝对时序:类首次初始化时,先执行全部静态代码块(按声明顺序);随后 main 方法开始执行,遇到局部代码块即刻运行;当执行 new X() 时,才依次触发实例代码块和构造器。


















