Loading

关于一个构造方法中this()和super()的执行顺序?

1.通过this()调用其它构造方法,必须位于本构造方法的第一句
2.构造方法中如果第一行没有显示调用super();,那么Java都会隐式调用super();,作为父类的初始化方法
那这两个在内存中到底谁先执行呢?

假定这里讨论的构造器都没有显式的super()调用:

  • 有显式this()调用的构造器就会抑制掉该构造器里隐式的super()调用;
  • 没有显式this()调用的构造器则会得到隐式的super()调用。

this()调用会借助别的重载版本的构造器来做部分初始化,而一连串this()最后来到的构造器必然是没有显式this()调用的,这里就会有显式或隐式的super()调用。

public class Base {
    private int x;
    public Base() {
        // super(); // 这里开头没有this()调用,编译器会合成隐式的super()调用
        this.x = 42;
    }
}

public class Derived extends Base {
    private char c;
    private Object o;

    public Derived() {
        this('a'); // 这里开头有this()调用,编译器不会合成隐式的super()调用
    }

    public Derived(char c) {
        this(c, null); // 同上,不会合成super()调用
    }

    public Derived(char c, Object o) {
        // super(); // 这里开头没有this()调用,编译器会合成隐式的super()调用
        this.c = c;
        this.o = 0;
    }
}

在这个例子里,如果有 new Derived(),则一连串的构造器调用会是:

Derived()                 // 最初的new
  Derived(char)           //   经过this()
    Derived(char, Object) //     经过this()
      Base()              //       经过super()
        Object()          //         来到Object()

这就是我想说的,一连串this()的最后一个必然不再会在开头有this()调用,而这个开头没有this()调用的构造器就会得到编译器给隐式合成的super()调用。
另外并不是“子类对象包含父类对象”,而是一个子类对象的实例会包含其所有基类所声明的字段,外加自己新声明的字段。那些父类声明的字段并不构成一个完整的父类的实例。super()是让父类封装对自己所声明的字段做初始化的手段。

posted @ 2022-11-13 22:56  听风blog  阅读(121)  评论(0编辑  收藏  举报