静态代码块优先级最高,类加载时执行且仅一次;构造代码块次之,每次new时在构造方法前执行;普通代码块最低,随方法调用按语句顺序执行。

Java中静态代码块和普通代码块的优先级不是靠“排查”,而是由JVM加载与实例化机制严格决定的——它不依赖运行时调试,而取决于代码在类结构中的位置和类型。只要理解三类代码块的本质和触发时机,就能准确预判执行顺序。
看清楚三类代码块的身份和触发时机
区分它们的关键不在写法多像,而在谁触发、何时触发、执行几次:
- 静态代码块(static {}):类加载时自动执行,只一次;不能访问实例成员;必须写在类体里,不能套在任何方法内
- 构造代码块({},无static):每次 new 对象时执行,在构造方法之前;可访问实例成员;属于对象初始化阶段
- 普通代码块(方法体内 {}):就是一段局部作用域代码,随方法调用而执行,和变量作用域规则一致;它不属于类初始化流程
验证优先级最直接的方式:打日志 + 观察输出顺序
不用复杂工具,一个简单main方法就能清晰呈现层级关系:
public class OrderTest {
static { System.out.println("1. 静态代码块"); }
{ System.out.println("2. 构造代码块"); }
public OrderTest() { System.out.println("3. 构造方法"); }
public static void main(String[] args) {
System.out.println("4. main开始");
{ System.out.println("5. 普通代码块A"); }
new OrderTest();
{ System.out.println("6. 普通代码块B"); }
new OrderTest();
}
}
输出结果固定为:
1. 静态代码块
4. main开始
5. 普通代码块A
2. 构造代码块
3. 构造方法
6. 普通代码块B
2. 构造代码块
3. 构造方法
这说明:静态代码块最先(且唯一一次),普通代码块按语句顺序穿插在方法流中,构造代码块紧贴每次new动作前。
立即学习“Java免费学习笔记(深入)”;
继承场景下要叠加父类/子类加载顺序
当存在父子类时,优先级逻辑扩展为:
- 先触发父类静态代码块(类加载时)
- 再触发子类静态代码块(子类被首次引用时加载)
- 接着父类构造代码块 → 父类构造方法
- 最后子类构造代码块 → 子类构造方法
注意:普通代码块仍只属于方法体内部,不会参与这个初始化链条——它只在对应方法执行到那行时才跑。
常见误判点提醒
容易混淆的地方往往来自命名或位置错觉:
- 把写在main里的{}当成“构造代码块”——其实是普通代码块,和类初始化无关
- 以为多个静态代码块会合并执行——实际是按定义顺序依次执行,且仅一次
- 尝试在静态代码块里调用非static方法或访问this——编译直接报错,因为此时还没有对象
- 在构造代码块里写return或throw——合法,但会跳过后续构造方法体内容(需谨慎)


















