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

Java初始化块执行疑问:为何调用两个构造器只执行一次?

为什么初始化块只执行了一次?

你的问题核心是对Java构造器链调用和初始化块的执行逻辑理解有误,下面给你拆解清楚:

关键规则:构造器链调用时,初始化块仅执行一次

Java编译器确实会把实例初始化块复制到每个构造器中,但有个前提:如果构造器的第一行是this()(调用同类其他构造器)或super()(调用父类构造器),那么当前构造器里的初始化块复制代码会被跳过。因为Java规定,实例初始化(包括初始化块和构造器代码)必须按固定顺序执行,不能重复执行初始化逻辑。

你的代码执行流程拆解

当你创建new First("Test")时,实际执行顺序是这样的:

  1. 进入参数化构造器First(String a),看到第一行是this(),立刻跳转到无参构造器First()。
  2. 无参构造器默认隐式调用super()(即Object类的构造器),完成父类初始化。
  3. 执行当前类的所有实例初始化块,按代码里的先后顺序:先打印A Block,再打印B Block。
  4. 执行无参构造器的自身代码:打印Inside default constructor。
  5. 回到参数化构造器,执行它自己的剩余代码:打印Inside parameterized constructor和String = Test。

整个过程中,初始化块只在无参构造器里被执行了一次,参数化构造器因为用this()跳转,跳过了自己内部的初始化块复制代码,所以不会重复打印。

验证修改:去掉构造器链调用试试

如果把参数化构造器里的this()删掉,改成:

First(String a){
    // 去掉this(),默认隐式调用super()
    System.out.println("Inside parameterized constructor");
    System.out.println("String = "+a);
}

这时分别调用new First()和new First("Test"),会发现两种情况都会各自执行一次初始化块,输出分别是:

  • new First():
    A Block
    B Block
    Inside default constructor
    
  • new First("Test"):
    A Block
    B Block
    Inside parameterized constructor
    String = Test
    

这就能印证编译器确实把初始化块复制到了每个构造器里,只是构造器链调用时会跳过当前构造器的初始化块逻辑,避免重复执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 01:13:59