图片中所示代码的输出是?
答:
base static
sub static
base构造代码块
base构造函数
sub构造代码块
sub构造函数
-
创建子类对象之前,首先执行类加载过程
先加载父类,于是父类中的静态代码块的代码先执行 -
父类加载完毕后,开始加载子类,于是子类静态代码块代码后执行
-
类加载过程完毕后,首先初始化父类对象,所以首先执行父类中的
构造代码块,在执行父类中的构造方法 -
然后在初始化子类成员,执行子类的构造代码块,子类的构造方法
子类和父类的执行顺序说明:
父类的静态初始化域,
子类的静态初始化域,
父类的非静态初始化域,
父类的构造函数,
子类的非静态初始化域,
子类的构造函数。
注意:初始化子类,但父类还没有初始化时,会先触发父类初始化
要特别注意子类在执行构造器时一定会先执行一个隐式的super()
这意味着子类调用构造器时要先执行父类的无参数构造器对父类进行初始化,如果父类没有无参构造器,则会出现编译错误,直接报错
这个过程的例子:
class Father
{
Father(){};
}
class Child extends Father
{
super(); //隐式地调用父类构造函数,对父类进行初始化
int age = 10;
Child(){};
}
若执行Child child = new Child();
(1)首先进行类加载(如果是首次使用这两个类),依次把父类和子类加载,对父类、子类变量进行初始化(int age=0);
(2)执行子类Child构造函数中的隐式super(),调用父类构造函数对父类进行初始化;
(3)执行子类Child构造函数中的其余部分,对子类进行初始化;
(4)对子类变量进行初始化(child.age = 10)
Java中子类对象初始化的过程参见:
https://blog.youkuaiyun.com/yangruijie1123/article/details/62948869