java中具有继承关系的类及其对象初始化顺序

先说结论

对于具有继承关系的类,它们的类和对象构造顺序为:父类的类构造器() -> 子类的类构造器() -> 父类成员变量的赋值和实例代码块 -> 父类的构造函数 -> 子类成员变量的赋值和实例代码块 -> 子类的构造函数。

小编整理了一些java进阶学习资料和面试题,需要资料的请加JAVA高阶学习Q群:664389243 这是小编创建的java高阶学习交流群,加群一起交流学习深造。群里也有小编整理的2019年最新最全的java高阶学习资料!

实验代码如下:

public class ExtensionTest {

public static void main(String[] args) {

new SubClass();

}

}

class SuperClass

{

{

System.out.println("我是父类实例块");

}

static {

System.out.println("我是父类类构造块");

}

public SuperClass()

{

System.out.println("我是父类构造函数块");

}

}

class SubClass extends SuperClass

{

{

System.out.println("我是子类实例块");

}

static {

System.out.println("我是子类类构造块");

}

public SubClass()

{

System.out.println("我是子类构造函数块");

}

}

结果:

我是父类类构造块

我是子类类构造块

我是父类实例块

我是父类构造函数块

我是子类实例块

我是子类构造函数块

解释:

类构造块是初始化类的时候执行的,而初始化类首先得加载类(不加载类进内存当然没法初始化)。

类实例块是放在该类构造函数最前面和父类构造函数之后执行的。因为子类的构造函数调用之前,会先调用父类的构造函数。

基于上述两条规则,我们再来看执行顺序。

new SubClass()也就是要构造SubClass这个类的一个对象,而要构造这个对象,首先必须把这个类的描述、定义加载进内存(类加载)。因此要先加载这个类(不过此时还未初始化)。

加载完这个类之后,想要构造这个类的对象。但是此时这个类的静态变量还未被初始化,因此要先初始化这个类,但是初始化这个类需要先初始化它的父类,因此此时就变成了,加载父类->初始化父类(调用静态块,即类构造块)

->初始化子类(调用静态块,即类构造块)。

然后就可以构造这个类的对象了,构造这个类的对象之前,要先构造父类对象,因此会先调用父类的构造函数,而调用父类构造函数之前又会先调用父类的实例块。

然后就到了子类构造函数,然而执行之前一样要先调用子类的实例块,最后才是子类的构造函数的函数体。

小编整理了一些java进阶学习资料和面试题,需要资料的请加JAVA高阶学习Q群:664389243 这是小编创建的java高阶学习交流群,加群一起交流学习深造。群里也有小编整理的2019年最新最全的java高阶学习资料!

猜你喜欢

转载自blog.csdn.net/weixin_42784331/article/details/87909125