黑马程序员技术交流社区

标题: 一个我不能理解的问题 [打印本页]

作者: pengbeilin    时间: 2015-8-17 17:40
标题: 一个我不能理解的问题
本帖最后由 pengbeilin 于 2015-8-17 19:55 编辑
  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
帮我分析一下为什么会是这样!
谢谢各位 !问题以解决!
作者: liuch111    时间: 2015-8-17 18:22
z继承x
所以 z实例化时先调用父类的默认构造函数
作者: boboyuwu    时间: 2015-8-17 18:22
就应该是这样的呀
作者: 黄蒙    时间: 2015-8-17 18:42
先找主函数,主函数为静态的,那么他将第一个运行。主函数中 new Z( );,即建立一个Z的对象,此时注意到Z继承了X那么现到父类中执行建立父类成员变量--执行父类构造函数的过程。父类中有一句Y b = new Y( );,即先建立1个Y的对象,此时调用Y的构造函数输出一个Y。继续执行父类X中的构造函数,输出第二个X,父类中的成员变量和构造函数都执行完毕后返回子类Z执行本身的成员变量和构造函数; 即先执行Y y = new Y( );,又输出一个Y,再执行Z(){System.out.print("Z");}输出最后一个Z。到这里程序执行结束打印结果为YXYZ
作者: pengbeilin    时间: 2015-8-17 19:18
liuch111 发表于 2015-8-17 18:22
z继承x
所以 z实例化时先调用父类的默认构造函数

去调用构造函数 构造函数中只有一个输出语句而已 ,Y b = new Y( )这句并没有在构造函数里面啊
作者: pengbeilin    时间: 2015-8-17 19:24
黄蒙 发表于 2015-8-17 18:42
先找主函数,主函数为静态的,那么他将第一个运行。主函数中 new Z( );,即建立一个Z的对象,此时注意到Z继 ...

我可以理解第二个Y的输出 却很难理解第一个Y的输出  第二个new Y是在Z类的成员位置,new Z的时候会去运行到那个地方, 但是第一个Y不过就是子类Z去调用了父类X的构造函数 并没有去new一个X的对象啊、那为什么要去执行那个X类 中的 new Y


作者: sven556677    时间: 2015-8-17 19:31
疯狂java讲义p161(175/914)”普通初始化块,声明实例属性指定的默认值都可以认为是对象的初始化块代码,他们的执行顺序与源程序中的排列顺序相同。“
你代码里的“Y b = new Y( );”就等于{sop("Y")};这个初始化代码块。
你可以在这句话的前后句分别加上一个初始化块的{System.out.println("初始化带买块前/后")};来看效果。

2015-08-17_192632.jpg (150.06 KB, 下载次数: 19)

2015-08-17_192632.jpg

作者: sven556677    时间: 2015-8-17 19:38
加载顺序父类静态,子类静态,父类对象初始化,父类构造函数,子类对象初始化,子类构造函数

1.jpg (127.93 KB, 下载次数: 19)

1.jpg

2.jpg (152.84 KB, 下载次数: 22)

2.jpg

3.jpg (150.95 KB, 下载次数: 12)

3.jpg

4.jpg (148.54 KB, 下载次数: 15)

4.jpg

5.jpg (148.85 KB, 下载次数: 19)

5.jpg

作者: 黄蒙    时间: 2015-8-17 19:51
pengbeilin 发表于 2015-8-17 19:24
我可以理解第二个Y的输出 却很难理解第一个Y的输出  第二个new Y是在Z类的成员位置,new Z的时候会去运行 ...

建立了一个类对象的时候不仅是要调用他的构造函数而且更要先初始化他的成员变量,当这个类继承了一个父类的时候你同时也要先初始化父类的成员变量啊,再调用父类的构造函数。。。哪有只调用父类的构造函数不初始化父类的成员变量的??同理在初始化父类的时候父类中那句Y b = new Y( )也要初始化的!
作者: pengbeilin    时间: 2015-8-17 19:54
sven556677 发表于 2015-8-17 19:31
疯狂java讲义p161(175/914)”普通初始化块,声明实例属性指定的默认值都可以认为是对象的初始化块代码,他 ...

受教受教!!!天天看视频还是太局限了!!一直以为写在大括号中的才算构造代码块!!!原来如次!!!
也就是说 属性 和 new对象都算是构造代码块!!
作者: 黄蒙    时间: 2015-8-17 19:54
黄蒙 发表于 2015-8-17 19:51
建立了一个类对象的时候不仅是要调用他的构造函数而且更要先初始化他的成员变量,当这个类继承了一个父类 ...

也就是说在这个例子里顺序就是父类成员变量,父类构造函数,子类成员变量,子类构造函数。
作者: pengbeilin    时间: 2015-8-17 19:56
黄蒙 发表于 2015-8-17 19:54
也就是说在这个例子里顺序就是父类成员变量,父类构造函数,子类成员变量,子类构造函数。 ...

谢谢解释! 一直都不知道成员位置也算是构造代码块的一部分!十分感谢




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