写点什么

《零基础学 Java》 FAQ 之 11- 为什么构造方法中调用重载的构造方法必须得是在第一行

用户头像
臧萌
关注
发布于: 2020 年 05 月 23 日
《零基础学 Java》 FAQ 之 11-为什么构造方法中调用重载的构造方法必须得是在第一行

@甜~ 在构造方法一节问到


老师,为什么构造方法中调用重载的构造方法,必须得是在第一行,有什么特殊考虑吗

DNT 回复:我好像在视频里提过一句, 但是是在后面讲解 super 的时候. 如果不从继承关系的角度看, 让 this 放在第一行确实是没有硬道理的.


回答


后面讲到 super 的时候, 也就是下面两节:


71 | super:和父类对象沟通的桥梁


72 | super:调用父类的构造方法


会讲到, 子类的构造方法, 会强制在第一行调用父类的构造方法. 这一点和 this 要在第一行有关联. 而这一点, 也正是给了构造方法调用别的构造方法, 必须是第一行给了一个强理由.


首先说一下为什么"子类的构造方法, 会强制在第一行调用父类的构造方法", 这个我在视频里提了一句, (人工划重点)这是因为子类可以访问父类的方法和属性. 那么必须保证子类的对象在做任何事情之前, 子类里那个隐含的父类对象, 必须初始化完成. 否则, 初始化都没完成, 调用方法, 返回属性, 都可能得到的是不对的状态/值(人工划重点结束).


那么这里说的初始化是什么呢?就是给对象里的属性设置正常的值,或者执行一些方法。简单来说,创建一个对象可以分为两步,一步是在堆上分配内存,然后在这个内存里存储对象的属性。下一步就是初始化对象,也就是执行构造方法。只有执行完毕构造方法,这个对象才算是可以被使用了。


这里可能有的一个疑问是,对象都创建出来了,初始化不初始化的不都能用么?其实不是那么回事儿。对象初始化可以做的事情很多,比较普遍的是初始化属性的值,也可能会调用一些方法,完成一些业务逻辑要求的初始化代码。从业务逻辑上来说,对象没有初始化完,是不应该被使用的。


举个例子,在堆上分配内存,就是买了一堆电脑硬件,什么内存,CPU,硬盘主板。初始化就是把这些零件拼装起来,组成一个电脑,并且给它装上操作系统。在完成初始化之前,电脑不是能被使用的电脑,只是一堆零件。同样的道理,在完成初始化之前,对象也不是对象,只是一堆内存。


好, 知道了这一点之后, 很自然的可以推出, this 调用必须也在第一行, 否则的话, this 调用里会调用父类构造方法, 如果 this 不是第一句, 那么也就隐含着调用父类构造方法不是第一句, 也就是说, 子类可能使用的父类的属性或者方法是没有初始化完成的.


其实我也觉得这个挺别扭, 拿参数稍微算一下,再给构造方法不行吗? 但是这个确实很难控制, 或者说没必要做这么复杂. 是给自己挖坑. 所以干脆一刀切, super 必须是第语句, this 也必须是第一句.




这篇文章来自极客时间推出的《零基础学Java》中的 FAQ。除了在每节视频课下方回答大家的问题之外,针对大家提出的优质问题或者普遍问题,如果需要更大篇幅的文章解答,则会在 FAQ 中以文章的方式给出回答。带你零基础入门,夯实 Java,课程地址:https://time.geekbang.org/course/intro/181


发布于: 2020 年 05 月 23 日阅读数: 71
用户头像

臧萌

关注

一线程序员,偶尔写写字 2017.10.20 加入

《零基础学 Java》,《职场求生攻略》 视频课作者 《Java入门1·2·3》作者

评论

发布
暂无评论
《零基础学 Java》 FAQ 之 11-为什么构造方法中调用重载的构造方法必须得是在第一行