Java继承中,代码执行顺序的问题?

来自《On Java》基础卷176页的例子,进行了精简。

class Shape {
    Shape() {
        System.out.println("Shape");
    }
}

class Line extends Shape {
    Line() {
        super();
        System.out.println("Line");
    }
}

public class CADSystem extends Shape {
    private Line li = new Line();
    public CADSystem() {
        super();
        System.out.println("CADSystem");
    }
    public static void main(String[] args) {
        CADSystem x = new CADSystem();
    }
}

执行结果如下

Shape
Shape
Line
CADSystem

按照本书之前的说法

变量定义会在任何方法(包括构造器)调用之前被初始化

所以我认为是先执行new Line(),输出 Shape、Line
然后执行CADSystem的构造器,输出 Shape、CADSystem
为什么会先输出两个Shape ?

阅读 1.3k
1 个回答

基类初始化是在变量之前的。

即便是在构造函数里显式调用的 super() ,成员的变量初始化也会被插入 super() 跟剩余的构造函数体之间。

https://docs.oracle.com/javas...

Just before a reference to the newly created object is returned as the result, the indicated constructor is processed to initialize the new object using the following procedure:

  1. Assign the arguments for the constructor to newly created parameter variables for this constructor invocation.
  2. If this constructor begins with an explicit constructor invocation (§8.8.7.1) of another constructor in the same class (using this), then evaluate the arguments and process that constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason; otherwise, continue with step 5.
  3. This constructor does not begin with an explicit constructor invocation of another constructor in the same class (using this). If this constructor is for a class other than Object, then this constructor will begin with an explicit or implicit invocation of a superclass constructor (using super). Evaluate the arguments and process that superclass constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, continue with step 4.
  4. Execute the instance initializers and instance variable initializers for this class, assigning the values of instance variable initializers to the corresponding instance variables, in the left-to-right order in which they appear textually in the source code for the class. If execution of any of these initializers results in an exception, then no further initializers are processed and this procedure completes abruptly with that same exception. Otherwise, continue with step 5.
  5. Execute the rest of the body of this constructor. If that execution completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, this procedure completes normally.
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏