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

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

















