
Java继承中构造器执行顺序详解:揭秘两次“shape”输出之谜
本文分析一段Java继承代码,解释其构造器执行顺序,并解答为何出现两次“shape”输出的疑惑。
以下代码片段来自《on java》基础卷,展现了Java继承中构造器调用的非直观特性:
<code class="java">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(); // 关键点1
    public CADSystem() {
        super(); // 关键点2
        System.out.println("CADSystem");
    }
    public static void main(String[] args) {
        CADSystem x = new CADSystem();
    }
}</code>运行结果为:
立即学习“Java免费学习笔记(深入)”;
<code>Shape Shape Line CADSystem</code>
与预期结果(Shape, Line, Shape, CADSystem)不符。 这并非简单的变量初始化优先于方法调用,而是Java构造器执行顺序的体现。
关键在于理解Java构造器初始化的步骤:
成员变量初始化:  在CADSystem类的构造器执行之前,其成员变量li会被初始化。  li的初始化需要调用Line的构造器,而Line的构造器又会调用Shape的构造器,因此第一次输出"Shape"。
父类构造器调用:  CADSystem的构造器显式调用了super() (关键点2),这会调用Shape的构造器,导致第二次输出"Shape"。
构造器主体执行:  接着,Line构造器的剩余部分执行,输出"Line"。最后,CADSystem构造器的剩余部分执行,输出"CADSystem"。
因此,输出顺序为"Shape" (来自li的初始化), "Shape" (来自super()), "Line", "CADSystem"。  这并非变量初始化在方法调用之前那么简单,而是Java语言规范中对构造器初始化顺序的严格规定导致的。  父类构造器的调用发生在子类构造器主体执行之前,而成员变量的初始化又发生在父类构造器调用之前。
总而言之,理解Java中构造器执行顺序的关键在于:成员变量初始化 -> 父类构造器调用 -> 子类构造器主体执行。 这三个步骤的顺序是固定的,并且成员变量的初始化会触发一系列的构造器调用,这在继承关系中尤为重要。
以上就是Java继承中构造函数的执行顺序:为什么会出现两次Shape输出?的详细内容,更多请关注php中文网其它相关文章!
                        
                        每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
                Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号