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()是让父类封装对自己所声明的字段做初始化的手段。