Java中的静态代码块是伴随类加载过程执行的代码逻辑,当类中存在多个静态代码块时,其执行顺序有固定的规则,同时还会和静态变量、实例相关的初始化逻辑产生优先级差异。理解这些规则有助于我们正确编写类初始化的相关代码,避免出现逻辑错误。

静态代码块的基础定义
静态代码块使用static关键字修饰,定义在类中方法外,用于初始化类的静态资源。它的语法格式如下:
public class Demo {
// 静态代码块
static {
System.out.println("静态代码块执行");
}
}
静态代码块在类被加载到内存时执行,且只会执行一次,无论后续创建多少个该类的实例,都不会再次执行。
多个静态代码块的执行顺序规则
当同一个类中存在多个静态代码块时,执行顺序严格按照代码中定义的先后顺序执行,先定义的静态代码块先执行,后定义的后执行。我们可以通过以下示例验证:
public class StaticBlockOrder {
// 第一个静态代码块
static {
System.out.println("第一个静态代码块执行");
}
// 静态变量
private static int num = initNum();
// 第二个静态代码块
static {
System.out.println("第二个静态代码块执行,num的值为:" + num);
}
// 静态变量初始化方法
private static int initNum() {
System.out.println("静态变量初始化方法执行");
return 10;
}
public static void main(String[] args) {
System.out.println("main方法执行");
}
}
上述代码的执行结果为:
第一个静态代码块执行 静态变量初始化方法执行 第二个静态代码块执行,num的值为:10 main方法执行
从结果可以看出,多个静态代码块和静态变量的初始化是交替执行的,整体顺序按照代码在类中出现的先后顺序排列,先出现的静态代码块或静态变量初始化逻辑先执行。
类初始化的完整顺序规则
除了静态代码块,类中还存在静态变量、构造代码块、构造方法等初始化相关的逻辑,完整的初始化顺序优先级从高到低为:
- 父类静态相关的初始化逻辑(静态变量、静态代码块),按照定义顺序执行
- 子类静态相关的初始化逻辑(静态变量、静态代码块),按照定义顺序执行
- 父类实例相关的初始化逻辑(构造代码块、实例变量初始化),按照定义顺序执行
- 父类构造方法执行
- 子类实例相关的初始化逻辑(构造代码块、实例变量初始化),按照定义顺序执行
- 子类构造方法执行
我们可以通过父子类的示例验证这个顺序:
// 父类
class Parent {
// 父类静态代码块
static {
System.out.println("父类静态代码块执行");
}
// 父类构造代码块
{
System.out.println("父类构造代码块执行");
}
// 父类构造方法
public Parent() {
System.out.println("父类构造方法执行");
}
}
// 子类
class Child extends Parent {
// 子类静态代码块
static {
System.out.println("子类静态代码块执行");
}
// 子类构造代码块
{
System.out.println("子类构造代码块执行");
}
// 子类构造方法
public Child() {
System.out.println("子类构造方法执行");
}
public static void main(String[] args) {
System.out.println("创建第一个子类实例");
new Child();
System.out.println("创建第二个子类实例");
new Child();
}
}
上述代码的执行结果为:
父类静态代码块执行 子类静态代码块执行 创建第一个子类实例 父类构造代码块执行 父类构造方法执行 子类构造代码块执行 子类构造方法执行 创建第二个子类实例 父类构造代码块执行 父类构造方法执行 子类构造代码块执行 子类构造方法执行
可以看到静态相关的逻辑只在类加载时执行一次,而实例相关的逻辑每次创建对象都会执行,且父类的初始化逻辑优先于子类执行。
常见注意事项
- 静态代码块中不能访问非静态的变量和方法,因为非静态成员属于实例,此时还没有实例被创建
- 如果静态变量初始化依赖静态代码块中的逻辑,需要注意两者的定义顺序,避免出现未初始化的变量被使用的情况
- 静态代码块抛出的异常会导致类初始化失败,后续无法再使用该类的静态成员或创建实例
类初始化阶段是类加载过程的最后一步,静态代码块和静态变量的初始化都在这个阶段完成,理解执行顺序规则是掌握Java类加载机制的重要基础。
总结
Java中多个静态代码块的执行顺序严格按照代码中定义的先后顺序执行,和静态变量初始化逻辑交替按出现顺序执行。完整的类初始化顺序遵循父类静态优先、子类静态次之、父类实例再次、子类实例最后的规则。开发时需要根据这些规则合理安排初始化逻辑的顺序,避免出现依赖错误。