A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Jim-剣◆﹏ 高级黑马   /  2013-11-1 12:08  /  894 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

希望哟大神能够清晰的易懂的帮我解释一下下面代码的详细执行的过程,思考了很久,没有理清

  1. class X {
  2.         Y b = new Y();
  3.         X() {
  4.                         System.out.print("X");
  5.         }
  6. }

  7. class Y {
  8.         Y() {
  9.                         System.out.print("Y");
  10.         }
  11. }

  12. public class Z extends X {
  13.         Y y = new Y();
  14.         Z() {
  15.                         System.out.print("Z");
  16.         }

  17.         public static void main(String[] args) {
  18.                         new Z();
  19.         }
  20. }
复制代码
我的理解是:
程序先执行new(),由于Z继承于X,那么先调用X的构造方法,输出X
然后执行Z的构造方法,输出Z
最终的结果应该是XZ才对...不怎么理解


评分

参与人数 1技术分 +1 收起 理由
黄炳期 + 1

查看全部评分

6 个回复

倒序浏览
java 构造函数的执行过程
类初始化时构造函数调用顺序:
(1)初始化对象的存储空间为零或null值;
(2)调用父类构造函数;
(3)按顺序分别调用类成员变量和实例成员变量的初始化表达式;
我的理解是:
构造器一般用来为成员变量赋值:public X(Y y) { this.y = y }
这说明 this.y 是先于构造体中的代码而创建的,
创建成员变量时系统会直接调用初始表达式,若为空,则赋默认值(int=0,Object=null...)

评分

参与人数 1技术分 +1 收起 理由
黄炳期 + 1

查看全部评分

回复 使用道具 举报
零下五度的水 发表于 2013-11-1 12:40
java 构造函数的执行过程
类初始化时构造函数调用顺序:
(1)初始化对象的存储空间为零或null值;

不够浅显,看不懂,我的意思是,能不能带我把这段代码走一遍
每一步执行什么,输出什么,最后的结果是什么,这样我好理解
回复 使用道具 举报
搜索黑马前辈的帖子,有一篇正好有谈到这个问题
http://bbs.itheima.com/forum.php?mod=viewthread&tid=57820&reltid=95561&pre_thread_id=0&pre_pos=4&ext=
主要观点是:
当父类,和子类有Static时,先初始化Static,再初始化子类的Static,再初始化父类的其他成员变量->父类构造方法->子类其他成员变量->子类的构造方法。
父类上层还有父类时,总是先执行最顶层父类的Static-->派生类Static-->派生类Static-->.......-->子类Static-->顶层父类的其他成员变量-->父类构造方法--> 派生类的其他成员变量 --> 派生类构造方法--> ...............-->子类其他成员变量-->子类构造方法(摘自傲鸽的帖子)
其实继承父类,在实例化子类的时候,调用父类构造方法其实还隐含了一个信息,就是会初始化父类的变量。
这样说会更好:实例化子类,先实例化父类(而不单单说只调用父类构造方法)
所以我这个代码的正确执行顺序应该是
new Z();--->先实例化父类(执行Y b = new Y();输出:Y,然后输出X),然后回到X类中,执行Y y = new Y();输出Y,最后再执行Z类的自身的构造函数,输出Z

所以最后的结果YXYZ就是这么来的
回复 使用道具 举报
new Z();  --创建一个Z的对象
这时候在堆上开辟一个空间生成Z的对象相关信息
这个信息要包括父类的信息吧
所以它要先在空间上生成一个父类的相关信息
从哪开始呢?成员变量啊,因为成员变量不会调用方法,方法却离不开成员变量
所以跑了一遍X里的Yb=new(Y)
它一看,这还有个new(Y),又是一个对象
得存进来吧,
它又开始存这个Y的信息,
一看Y里就一个构造函数,
直接存了这个就完了呗,就跑了一遍syso:Y
回头继续存父类X的信息
存完了变量开始存方法吧,就跑了一遍syso:X
存完了父类的再回头存自己的吧
这个跟上面差不多,就略了吧
回复 使用道具 举报
零下五度的水 发表于 2013-11-1 13:34
new Z();  --创建一个Z的对象
这时候在堆上开辟一个空间生成Z的对象相关信息
这个信息要包括父类的信息吧

懂了,谢谢
回复 使用道具 举报
帖子已重新分类。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马