看面试题有感:子类构造器(无参或有参)继承的super()方法在何时调用,与静态代码块,普通代码块相比的执行顺序如何的思考及证明

-----------------------------------第二次更新----------------------------------

在对java基础复习之后,我对本文末尾的问题有了答案。原来创建子类会先把父类进行加载,但是并不会初始化成对象,只是进行了加载和连接,所以静态代码块会先执行

然后是super()什么时候执行,super()是在子类初始化的过程中执行,因为父类必须先初始化,所以说super()会在子类的构造器调用的过程中,是过程中,也就是说此时子类还没完成初始化。刚好过程中初始化父类,所以从顺序上看

父类是先完成初始化,子类再完成初始化,这也与super()在子类构造器第一行代码的硬性要求相吻合,不得不说开发人员的语法设计还是很精妙的

------------------------------------

首先我们要明确的两个java语法规定是

1.执行顺序:静态代码块>普通代码块>构造方法

2.子类的构造过程中必须调用父类的构造方法

先上代码,我们再一步步分析

class Father{
    public Father(){
        System.out.println("1111111");
    }
    {
        System.out.println("2222222");
    }
    static{
        System.out.println("3333333");
    }
}
class Son extends Father{
    public Son(){
        //super();
        System.out.println("4444444");
    }
    {
        System.out.println("5555555");
    }
    static {
        System.out.println("6666666");
    }
}

public class MethodOrderTest {
    public static void main(String[] args) {
        new Son();
    }
}

在不执行以上代码的时候我们来分析输出结果

1.本类编译,然后在编译两个从类的时候,Father类先编译,Son类后编译,所以静态代码块输出顺序1:3333333最先输出,之后是输出顺序2:6666666

2.开始执行new Son(),

这个时候就有一个疑问了,根据第2个java语法我们知道super()这个隐含方法是存在于子类的构造器中的,我在代码中也通过注释表达出来了,于是一开始的我认为既然存在super(),并且看了很多人的博客写的都是super()方法是调用父类构造器的

这样一来我就觉得应该是执行Son这个子类,等执行到super()的时候再创建父类,那么按照第一个java语法可知应该输出的是输出顺序3:5555555

之后执行到Son的构造器,先执行super(),如下,那么应该为输出顺序4:2222222,接着输出顺序5:1111111

public Son(){
        //super();
        System.out.println("4444444");
    }

最后置信Son构造器的最后一行代码,输出顺序6:4444444

---------------------------------------------------------------分割线-------------------------------------------------------------

然而实际正确的输出顺序是

3333333
6666666
2222222
1111111
5555555
4444444

可以看到从输出顺序3就已经出错了,那么这是为什么呢,按照super()的定义来说没有问题,的确是调用父类构造器创建父类对象,而且super()的执行顺序也没有问题,在构造器中就是低于普通代码块和静态代码块执行的

为了解决上面的疑问,我看了一些博客,但是可能是关键词搜索不对,所以并没有找到满意的答案

-------------------------------------------------------------------------------------------------------------------------------------------------------

于是根据我的理解和面试题的解释,我写出想法总结如下:

子类在创建的时候会先创建父类对象,可能是通过super()创建(因为不确定我只能用可能来形容)

但是创建的优先级是优于子类的创建代码,意思就是想要创建子类的Class对象,必须先创建父类的Class对象,无关super()这行代码的位置和执行顺序

综上

留下一个问题,super()到底啥时候执行,希望有人能告知一下

原文地址:https://www.cnblogs.com/skyvalley/p/13825859.html