黑马程序员技术交流社区

标题: 关于子父类中代码块的执行顺序问题 [打印本页]

作者: szl77777    时间: 2016-1-19 22:20
标题: 关于子父类中代码块的执行顺序问题
冯佳老师视频中有一处疑问,请各位大神请教:有两个类,一个父类,一个子类,父子类中分别有静态代码块,构造代码块,构造函数,假设分别为A B C 和X Y Z,按照老师讲的顺序是:A-X-B-C-Y-Z,其中我的疑问是:父类构造代码块和构造函数是由子类构造函数调用的,执行顺序必然在子类构造函数之前,这个我理解。可是老师也讲过:在同一个类中执行顺序是:静态代码块--构造代码块--构造函数;也就是说在子类构造函数调用之前,子类构造代码块先执行,顺序不应该是:A-X-Y-B-C-Z,也就是说子类代码块不应该排在父类代码块之前吗?
作者: 舞动炫龙    时间: 2016-1-19 22:32
创建对象子类对象调用的空参构造Zi z = new Zi();
空参构造第一句默认是super();
执行super();的时候就会先找构造代码块在执行空参构造,子类同理
作者: 黑色皮肤的马    时间: 2016-1-19 22:38
首先把父类加载进内存,所以父类静态代码块执行了。然后子类加载进内存,Zi z = new Zi();子类要创建对象,并且用的是空参构造,空参构造有隐式语句super();这时会先去调用父类的空参构造。但是父类有构造代码块,先执行父类构造代码块,再执行父类构造方法,这时,才把 super()走完。然后创建子类对象,先走子类构造代码块,再走子类构造方法。
作者: ZEROCRF    时间: 2016-1-19 22:45
我支持楼主的观点,先走子类构造代码块再走父类构造代码块
作者: szl77777    时间: 2016-1-19 22:47
其实我最想知道的是,子父类执行时内存中的详解。
作者: furuigang    时间: 2016-1-19 23:34
要弄清楚这个问题,就必须知道“构造代码块”产生的原因,以及其本质。
构造代码块:多个构造方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行。
也就是说,实际上构造代码块中的内容其本质还构造方法中的一部分,创建对象时的入口还是构造方法。
本质上,构造代码块中与构造方法是一体的,构造代码块中的内容,体现在构造方法当中的位置应该是在
super();语句与构造方法内容之间的那部分内容
(注:见附图“构造代码块中的内容体现在构造方法当中应该是这样.png”)
那么当创建类的对象的时候,就会调用类的构造方法,首先执行其公共的部分,也就是“构造代码块”当中的内容。
回到子类继承父类,并创建对象的这个题中,执行流程应该是这样:
1、将父类的.class文件加载进方法区,父类静态代码块随之执行
2、将子类的.class文件加载进方法区,子类静态代码块随之执行
3、创建子类对象,默认访问父类的构造方法,父类的构造代码块执行,父类的构造方法执行
4、访问子类的构造方法,子类的构造代码块执行,子类的构造方法执行
5、子类对象创建完毕
(注:见附图“执行流程.png”)

构造代码块中的内容体现在构造方法当中应该是这样.png (105.04 KB, 下载次数: 43)

构造代码块中的内容体现在构造方法当中应该是这样.png

执行流程.png (100.66 KB, 下载次数: 33)

执行流程.png

作者: furuigang    时间: 2016-1-19 23:37
szl77777 发表于 2016-1-19 22:47
其实我最想知道的是,子父类执行时内存中的详解。

一会儿回来画内存图给你
作者: 王海平    时间: 2016-1-20 00:16
顶!d=====( ̄▽ ̄*)b。。。。
作者: 洋葱头头    时间: 2016-1-20 10:23
ZEROCRF 发表于 2016-1-19 22:45
我支持楼主的观点,先走子类构造代码块再走父类构造代码块

可惜 不是那样的
作者: szl77777    时间: 2016-1-20 21:33
感觉JVM很深啊
作者: szl77777    时间: 2016-1-21 15:49
学习中总有疑惑啊,幸亏有大神
作者: z195061    时间: 2016-1-21 15:54
回复有奖励
作者: Android666    时间: 2016-1-21 16:49
父类构造代码块是抽取构造方法中的相同元素,构造函数对父类属性进行初始化。供子类使用。不应该理解成被子类构造函数调用吧!因为是子类继承父类,类加载时,先加载fu.class,在加载zi.class先执行父类中的静态代码块(静态随着类的加载而加载)接着执行子类静态代码块,之后父类构造代码块,构造方法。子类构造代码块,子类构造方法
作者: 曾宇    时间: 2016-1-21 17:16
本帖最后由 曾宇 于 2016-1-21 17:29 编辑

Fu f =new Zi();
在还没有读到这句话的时候,静态代码块就执行了。
静态优先于类的加载。静态执行完,加载Fu类,加载Zi类。
然后才读这句代码
读到这句话的时候,会执行父类中的构造代码块。你创建子类对象,相当于创建了先要创建父类对象
所以接着执行父类构造函数。最简单的一句话。父类还不存在呢,你子类去哪里继承父类。
然后才是子类构造代码块执行,构造函数执行。


作者: iori    时间: 2016-1-21 17:32
学习了,学习了。
作者: 划江北上    时间: 2016-1-21 20:38
2楼说的很仔细啊,同意2楼说法。
作者: zhanganping    时间: 2016-1-22 00:10
学习长见识了,共同成长进步
作者: szl77777    时间: 2016-1-23 23:40
嗯,我也懂了,调用构造函数时代码块才会执行
作者: 1900    时间: 2016-1-24 01:04
java基础很重要啊!初学者要努力。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2