• 看面试题有感:子类构造器(无参或有参)继承的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()到底啥时候执行,希望有人能告知一下

  • 相关阅读:
    自动化测试知识点汇总(200421)
    Mac_使用allure 生成测试报告
    mac_使用Charles抓取Firefox 链接
    工具列表
    Appium_iOS_Safari测试脚本(2)
    日志学习(一)
    java中==和equals的区别(转)
    jackson使用localdatetime转换json出现问题
    js复习--基础
    复习下CSS-零碎要点
  • 原文地址:https://www.cnblogs.com/skyvalley/p/13825859.html
Copyright © 2020-2023  润新知