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

  • 相关阅读:
    递归实现随机数不重复问题
    今天写的一个工厂工具类
    Win7 x64 IIS运行ASP+Access故障完美解决方法(转)
    li中,标题和日期一排,且日期靠右
    [学习笔记] extends implements 的区别与联系 [转载]
    [学习笔记] vim使用大全 [转]
    MidPoint Displacement for Terrain Rendering
    CryEngine3 打造另一个真实世界
    Hello C++ AMP!
    DetailMap For Terrain Rendering
  • 原文地址:https://www.cnblogs.com/skyvalley/p/13825859.html
Copyright © 2011-2022 走看看