Java构造器调用疑问:为何super相关代码执行情况存在差异?
疑问一:GoldenDelicious无参构造器的打印语句为何未执行?
提供的Test类代码如下:
public class Test { public static void main(String[] args) { Apple a = new Apple(); System.out.println(a); System.out.println("---------------"); GoldenDelicious g = new GoldenDelicious(7); System.out.println(g); System.out.println("---------------"); Apple c = new GoldenDelicious(8); System.out.println(c); } } class Apple { double weight; public Apple() { this(1); System.out.println("Apple no-arg constructor"); } public Apple(double weight) { this.weight = weight; System.out.println("Apple constructor with weight"); } @Override public String toString() { return "Apple: " + weight; } } class GoldenDelicious extends Apple { public GoldenDelicious() { this(5); System.out.println("GoldenDelicious non-arg constructor"); } public GoldenDelicious(double weight) { super(weight); this.weight = weight; System.out.println("GoldenDelicious constructor with weight"); } @Override public String toString() { return "GoldenDelicious: " + weight; } }
代码输出:
Apple constructor with weight Apple no-arg constructor Apple: 1.0
--------------- Apple constructor with weight GoldenDelicious constructor with weight GoldenDelicious: 7.0
--------------- Apple constructor with weight GoldenDelicious constructor with weight GoldenDelicious: 8.0
核心原因:main方法里从未调用过GoldenDelicious的无参构造器。所有创建GoldenDelicious实例的代码,都是调用带double参数的构造器(new GoldenDelicious(7)、new GoldenDelicious(8))。只有执行new GoldenDelicious()时,这个无参构造器才会被触发,进而执行里面的打印语句。
额外补充:就算调用了无参构造器,它第一行的this(5)会先调用本类的带参构造器,等带参构造器逻辑执行完毕后,才会回到无参构造器执行那行打印语句。
疑问二:调用super(color, filled);父类构造器后,子类构造器的后续代码为何还能执行?
Circle类的关键构造器代码:
public Circle(double radius, String color, boolean filled) { super(color, filled); this.radius = radius; System.out.println("does this print?"); }
Java构造器的执行规则是:子类构造器必须先完成父类的初始化(显式调用super()或隐式调用父类无参构造器),但父类构造器执行完毕后,会回到子类构造器继续执行剩余代码。
super(color, filled)仅负责调用父类GeometricObject的对应构造器,完成父类成员的初始化工作。这一步完成后,程序会回到当前的Circle构造器,继续执行this.radius = radius;和打印语句等子类自身的构造逻辑,所以那行打印语句会正常执行。
内容的提问来源于stack exchange,提问作者Linh Tran

