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

Java构造函数执行顺序疑问:代码输出与预期不符求解

Java构造方法执行顺序深度解析

问题描述

你运行以下Java代码:

public class App {
    public static void main(String[] args){
        new C();
        new C(1.0);
    }
}

class A {
    public A(){
        this(5);
        System.out.println("a1");
    }

    public A(int x){
        System.out.println("a2");
    }
}

class B extends A {
    public B(){
        this(false);
        System.out.println("b1");
    }

    public B(int x){
        super();
        System.out.println("b2");
    }

    public B(boolean b){
        this(2);
        System.out.println("b3");
    }
}

class C extends B {
    public C(){
        System.out.println("c1");
    }

    public C(double x){
        this();
        System.out.println("c2");
    }
}

实际输出为:a2 a1 b2 b3 b1 c1 a2 a1 b2 b3 b1 c1 c2,但你预期仅输出c1 c2,下面详细拆解执行逻辑。

核心规则铺垫

要理解执行顺序,必须明确Java构造方法的3个核心调用规则:

  • 子类构造方法如果没有显式调用super()(父类构造)或this()(自身其他构造),JVM会自动插入父类的无参构造调用
  • 构造方法中super()或this()必须是第一条语句,且两者不能同时出现
  • 构造方法的执行遵循从顶层父类到子类的逐层执行顺序:先完成父类构造的所有逻辑,再执行子类构造中的代码

逐行拆解执行流程

第一次实例化:new C()

  1. 调用C()构造,因无显式super()/this(),JVM自动调用父类B的无参构造B()
  2. 进入B(),第一条语句是this(false),调用B(boolean)构造
  3. 进入B(boolean),第一条语句是this(2),调用B(int)构造
  4. 进入B(int),第一条语句是super(),调用父类A的无参构造A()
  5. 进入A(),第一条语句是this(5),调用A(int)构造
  6. 执行A(int)中的System.out.println("a2") → 输出a2
  7. A(int)执行完毕,回到A(),执行后续代码System.out.println("a1") → 输出a1
  8. A()执行完毕,回到B(int),执行后续代码System.out.println("b2") → 输出b2
  9. B(int)执行完毕,回到B(boolean),执行后续代码System.out.println("b3") → 输出b3
  10. B(boolean)执行完毕,回到B(),执行后续代码System.out.println("b1") → 输出b1
  11. B()执行完毕,回到C(),执行后续代码System.out.println("c1") → 输出c1

这部分输出序列:a2 a1 b2 b3 b1 c1

第二次实例化:new C(1.0)

  1. 调用C(double)构造,第一条语句是this(),触发C()构造的完整执行(流程和上面完全一致,再次输出a2 a1 b2 b3 b1 c1)
  2. C()执行完毕,回到C(double),执行后续代码System.out.println("c2") → 输出c2

这部分输出序列:a2 a1 b2 b3 b1 c1 c2

最终输出合并

将两次实例化的输出拼接,得到最终结果:a2 a1 b2 b3 b1 c1 a2 a1 b2 b3 b1 c1 c2

误区总结

你预期仅输出c1 c2,是因为忽略了Java构造方法的继承链调用机制:子类对象创建时,必须先完成所有父类的构造初始化,才能执行自身构造的代码,这是Java保证父类成员变量能被正确初始化的核心逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 07:55:47