java代码块执行顺序由jvm严格决定:静态块在类首次主动使用时执行一次,实例块在每次new对象时、父类构造调用后且本类构造体前执行,父子类遵循先父后子、先静后动规则,局部块仅限作用域无初始化影响。

Java代码块执行顺序不是靠经验猜的,而是由JVM类加载和对象创建机制严格决定的。搞清静态块、实例块、构造器、方法内局部块各自的触发时机和先后关系,才能避免初始化异常、字段未赋值、父类调用子类重写方法时的空指针等问题。
静态代码块:类首次主动使用时只执行一次
它属于“类初始化阶段”,不是类一加载就跑,而是在第一次被主动使用时才触发。常见触发动作包括:
• new 某个类的实例
• 调用该类的 public static 方法
• 访问非编译期常量的 public static 字段(比如 public static int PORT = 8080;;但 public static final String MSG = "ok"; 不会触发)
• 反射调用 Class.forName("X")
多个静态块按源码从上到下依次执行。一旦某个静态块抛出未捕获异常,整个类初始化失败,后续对该类的任何主动使用都会直接抛出 ExceptionInInitializerError。
实例代码块:每次 new 对象时,在构造器体前自动执行
它写在类中、方法外,无 static 修饰,属于对象初始化的一部分。
执行位置非常明确:
• 父类 super() 调用完成之后
• 本类构造器方法体开始之前
编译器会把它“复制”到每个构造器开头,所以无论有多少个重载构造器,只要被调用,该块就执行一次。适合抽取多个构造器共有的初始化逻辑,比如统一设置默认状态或校验必要字段。
父子类初始化顺序:先父后子、先静后动
执行 new Child() 时,完整流程是:
• 父类静态变量初始化 → 父类静态代码块(仅首次)
• 子类静态变量初始化 → 子类静态代码块(仅首次)
• 父类实例变量初始化 → 父类实例代码块 → 父类构造方法
• 子类实例变量初始化 → 子类实例代码块 → 子类构造方法
注意:静态部分只走一遍;之后每次 new 都重复后四步。如果父类构造器里调用了可被子类重写的方法,要特别小心——此时子类字段可能尚未初始化(因子类实例代码块还没执行)。
方法内局部块:纯语法结构,与初始化无关
写在方法内部的 { },比如:
void test() {
int x = 1;
{
int y = x + 1;
System.out.println(y);
}
System.out.println(x);
}
它只是限制变量作用域、提前释放资源或提升可读性的语法糖,不参与类加载或对象初始化流程。
它的执行完全取决于方法是否被调用、执行流是否到达该位置。即使类从未初始化,只要方法被调用且走到这里,它就会运行。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











