Java初始化块执行疑问:为何调用两个构造器只执行一次?
为什么初始化块只执行了一次?
你的问题核心是对Java构造器链调用和初始化块的执行逻辑理解有误,下面给你拆解清楚:
关键规则:构造器链调用时,初始化块仅执行一次
Java编译器确实会把实例初始化块复制到每个构造器中,但有个前提:如果构造器的第一行是this()(调用同类其他构造器)或super()(调用父类构造器),那么当前构造器里的初始化块复制代码会被跳过。因为Java规定,实例初始化(包括初始化块和构造器代码)必须按固定顺序执行,不能重复执行初始化逻辑。
你的代码执行流程拆解
当你创建new First("Test")时,实际执行顺序是这样的:
- 进入参数化构造器
First(String a),看到第一行是this(),立刻跳转到无参构造器First()。 - 无参构造器默认隐式调用
super()(即Object类的构造器),完成父类初始化。 - 执行当前类的所有实例初始化块,按代码里的先后顺序:先打印
A Block,再打印B Block。 - 执行无参构造器的自身代码:打印
Inside default constructor。 - 回到参数化构造器,执行它自己的剩余代码:打印
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 constructornew First("Test"):A Block B Block Inside parameterized constructor String = Test
这就能印证编译器确实把初始化块复制到了每个构造器里,只是构造器链调用时会跳过当前构造器的初始化块逻辑,避免重复执行。
内容的提问来源于stack exchange,提问作者Shivam...
相关产品推荐
相关产品推荐

