黑马程序员技术交流社区

标题: 传智的一道基础题,为什么会这样输入 [打印本页]

作者: 姬光普    时间: 2015-5-18 19:43
标题: 传智的一道基础题,为什么会这样输入
代码
  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. }
复制代码

输出是:YXYZ,不太明白为什么这样输出
作者: 348532020    时间: 2015-5-18 20:04
应该是new z(),然后z类继承自X类,所以先初始化X类,进入X类以后创建Y 的对象,调用Y类的无参构造,输出一个Y,然后回到X继续往下走,走X的无参构造,输出一个X。X就初始化完成了,然后初始化Z。同理,先是创建了Y的对象,初始化了Y类,走了Y的无参,输出一个Y,再回到Z,走Z的无参,输出一个Z。 我推断应该是这样的。你用断点调试一下。
作者: 姬光普    时间: 2015-5-18 20:51
348532020 发表于 2015-5-18 20:04
应该是new z(),然后z类继承自X类,所以先初始化X类,进入X类以后创建Y 的对象,调用Y类的无参构造,输出 ...

脑子有点转不过来,为什么初始化x的时候回创建y啊,这是考察哪的知识点啊?
作者: 姬光普    时间: 2015-5-18 21:00
姬光普 发表于 2015-5-18 20:51
脑子有点转不过来,为什么初始化x的时候回创建y啊,这是考察哪的知识点啊? ...

自己好像明白点了。。。。。
作者: D.reamJA    时间: 2015-5-18 21:06
同学你好,当构造函数new对象的时候,先查看有无父类,如果有父类,就先执行父类的构造函数。在构造函数中,先进行变量初始化,初始化类中的成员。
所以如题,Z父类是X,X有成员变量,故new Y,首先输出Y。
然后X执行自己的构造函数,输出X。
Z的初始化变量,输出Y。
最后Z的构造函数,输出Z。
作者: 开弓没有回头箭    时间: 2015-5-18 21:42
又学到一点了
作者: 姬光普    时间: 2015-5-18 21:42
D.reamJA 发表于 2015-5-18 21:06
同学你好,当构造函数new对象的时候,先查看有无父类,如果有父类,就先执行父类的构造函数。在构造函数中 ...

非常感谢,我理解了
作者: 追梦德鲁    时间: 2015-5-18 21:57
围观大神
作者: 不能不改变    时间: 2015-5-18 22:05
成员变量的初始化在构造方法之前么。。。唉都忘光了 = =
作者: gaoer    时间: 2015-5-18 22:15
学到了 。, 好蛋疼的赶脚
作者: 黄冬    时间: 2015-5-18 22:44
确实有点迷惑性。。
作者: zhangjnia    时间: 2015-5-18 23:01
不错,学习了
作者: 王建伟    时间: 2015-5-19 00:09
这牵扯到JVM的运行流程,大致流程是这样的:
(流程1)先初始化静态:先父静态,再子静态;
(流程2)先父后子,先父的全部,然后子的全部;
(3)优先级:父类大于子类。静态代码块>非静态代码块>构造函数(与位置的前后无关)。
知道了上面的规则,然后分析:
1、程序以main()为入口,new Z();jvm查看程序发现没有静态变量或者静态代码块(流程1),此时就会想要调用类Z的构造函数进行进行初始化,然后发现Z是有父类的,这时候就(流程2)初始化父类的全部,程序上下执行,执行类X的 Y b = new Y();然后就调用了
类Y的构造器,输出了Y;
2、然后还是(流程2)未完的构造函数,此时输出X,此时父类的所有东西已经初始化完成了;
3、接着还是(流程2)执行子类Z的Y y = new Y(); 此时输出Y;
4、还是(流程2)执行子类的构造函数,输出Z
楼主可以试试断点调试,验证一下。是不是这样的流程的。

作者: 姬光普    时间: 2015-5-19 00:15
王建伟 发表于 2015-5-19 00:09
这牵扯到JVM的运行流程,大致流程是这样的:
(流程1)先初始化静态:先父静态,再子静态;
(流程2)先父 ...

嗯嗯。确实是这样的,真的非常感谢:)
作者: 王建伟    时间: 2015-5-19 00:18
姬光普 发表于 2015-5-19 00:15
嗯嗯。确实是这样的,真的非常感谢

客气了,楼主这么高的技术分了啊,我才五分,哎,不知道什么时候才能挣到足够的分
作者: 姬光普    时间: 2015-5-19 00:22
王建伟 发表于 2015-5-19 00:18
客气了,楼主这么高的技术分了啊,我才五分,哎,不知道什么时候才能挣到足够的分 ...

我的技术分真心不多,惭愧,我来论坛几天了,是用赚的黑马币兑换的,还有周末的技术答题,那个是直接给的技术分
作者: 林思奇    时间: 2015-5-19 00:24
这个是考谁先运行的问题,我也忘了顺序
作者: 王建伟    时间: 2015-5-19 00:25
姬光普 发表于 2015-5-19 00:22
我的技术分真心不多,惭愧,我来论坛几天了,是用赚的黑马币兑换的,还有周末的技术答题,那个是直接给的 ...

我注册三天吧,那个题目我也答了得了三分要不然还是2分呢,哈哈,楼主你准备走哪期啊?哪个方向?
作者: guoyangpeng    时间: 2015-5-19 07:37
学习了!赞一个
作者: 谷歌    时间: 2015-5-19 17:53
很经典的题目啊,留名学习!
作者: 破烂小白    时间: 2015-5-19 17:56

不错,学习了
作者: yihuihua    时间: 2015-5-19 18:52
这是在继承关系中,子类对象实例化过程?
作者: 探索者    时间: 2015-5-19 19:03
不能不改变 发表于 2015-5-18 22:05
成员变量的初始化在构造方法之前么。。。唉都忘光了 = =

类中成员变量的初始化是在构造方法之前,与先后顺序无关
作者: LoveMyself    时间: 2015-5-19 21:39
王建伟 发表于 2015-5-19 00:09
这牵扯到JVM的运行流程,大致流程是这样的:
(流程1)先初始化静态:先父静态,再子静态;
(流程2)先父 ...

我去,天天受教,辛苦呀
作者: LoveMyself    时间: 2015-5-19 21:41
哎呀,真心受教,都是大神呀
作者: niuapp    时间: 2015-5-19 21:51
受教了,大神
作者: 王先荣    时间: 2015-5-19 22:22
来围观了~~~
作者: 米江波    时间: 2015-5-19 22:36
学习了  原来我理解的不一样啊。。。




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