You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java继承场景下静态代码块与实例初始化块执行顺序问题

Java静态/实例代码块执行顺序规则说明

核心误区说明

你代码中标注为Static Block 2、Static Block 4的两个代码块没有加static修饰符,不属于静态代码块,是绑定到对象创建流程的实例构造代码块,二者执行时机完全不同,这就是你观察到Static Block 3先于Static Block 2执行的根本原因。

固定执行顺序规则

Java中类的初始化、对象创建流程在继承场景下遵循严格的先后顺序,整体分为两大阶段:

第一阶段:类加载初始化阶段(仅执行1次,类第一次被主动调用时触发)

这个阶段只执行静态相关逻辑,顺序为:

  • 先执行父类的静态变量赋值、父类静态代码块(按代码编写的先后顺序执行)
  • 父类静态逻辑全部执行完成后,再执行子类的静态变量赋值、子类静态代码块(按代码编写的先后顺序执行)

第二阶段:对象实例化阶段(每次new新对象都会执行1次)

类加载全部完成后才会进入实例创建流程,顺序为:

  • 先执行父类的实例变量赋值、父类实例构造代码块(按代码编写的先后顺序执行),之后执行父类构造方法
  • 父类实例构造逻辑全部完成后,再执行子类的实例变量赋值、子类实例构造代码块(按代码编写的先后顺序执行),之后执行子类构造方法

代码执行流程逐段拆解

测试代码如下:

class X{
    static String a = "ABC";

    static
    {
        a = a + "123";
        System.out.println("Static Block 1");
    }
    {
        a = "ABC123";
        System.out.println("Static Block 2"); // 无static修饰,属于实例构造代码块,不是静态块
    }
}

class Y extends X{
    static
    {
        a = a + "123ABC";
        System.out.println("Static Block 3");
    }
    {
        System.out.println("Static Block 4"); // 无static修饰,属于实例构造代码块,不是静态块
        System.out.println(a);
    }
}

public class MainClass {
    public static void main(String[] args) {
        Y y = new Y();
    }
}

运行结果:
运行结果

输出对应执行步骤:

  1. 执行main方法触发new Y()时,JVM发现Y类未加载,且Y继承自X,优先加载X类
  2. X类加载阶段:先给静态变量a赋值为"ABC",再执行X的静态代码块,a变为"ABC123",打印Static Block 1,X类加载完成
  3. 开始加载Y类:执行Y的静态代码块,a变为"ABC123123ABC",打印Static Block 3,Y类加载完成(此阶段还未进入对象创建流程,两个实例构造块都不会执行)
  4. 进入Y对象实例化流程,先构造父类X的实例部分:执行X的实例构造代码块,将a重新赋值为"ABC123",打印Static Block 2,之后执行X的隐式无参构造
  5. 父类实例构造完成,开始构造Y自身的实例部分:执行Y的实例构造代码块,先打印Static Block 4,再打印当前a的值"ABC123",之后执行Y的隐式无参构造,对象创建完成

内容的提问来源于stack exchange,提问作者Foody

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 02:54:21