对象创建问题

雅克布 2012-09-16 11:03:40
class X {
Y b = new Y();
X() {
System.out.print("X");
}
}
class Y {
Y() {
System.out.print("Y");
}
}

public class Z extends X {
//Y y = new Y();
Z() {
System.out.print("Z");
}
public static void main(String[] args) {
new Z();
}
}
如上代码,输出是YXZ,将注释去掉后为什么变成了YXYZ,主要是后三个字母,为什么X和Y的输出先后顺序不一样了,谁能帮我从底层对象创建方面分析透彻一点,有点搞不清。
...全文
215 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
Enagle_Wang 2012-09-18
  • 打赏
  • 举报
回复
主要还是子父类的初始化过程,最先开始的是静态变量,静态库,成员变量,构造方法。
注意,除开静态变量和静态块,其他的初始化过程先是初始化子类的在初始化父类。
安特矮油 2012-09-18
  • 打赏
  • 举报
回复
这样你会更清楚一点咯

class X {
Y y = new Y(1);

X() {
System.out.println("X");
}
}

class Y {
Y(int i){
System.out.println("Y " + i);
}
}

public Z Test extends X {
Y y = new Y(2);

Z() {
System.out.println("Z");
}

public static void main(String[] args) {
new Z();
}
}
cscript 2012-09-17
  • 打赏
  • 举报
回复
lz已经搞清楚 XYZ 了 多了个Y就不懂了? 后者比前者好理解的多
xiars123 2012-09-17
  • 打赏
  • 举报
回复
从你的提问看,你已经知道为什么第一次输出的是YXZ了;
第二次输出的YXYZ,与第一次相比,输出顺序并没有变化,XZ之间多了一个Y,是由于Y y = new Y();在Z()之前构造,但又必须在父类构造完成之后。
苦瓜_Young 2012-09-17
  • 打赏
  • 举报
回复
第一步new Z();使用Z的构造方法的时候首先要调用他的父类X的构造方法 只有当X构造出来了之后才能newZ的对象。这样说 明白了吗?去看看super()
江湖啊江湖 2012-09-17
  • 打赏
  • 举报
回复
楼主,建议你去弄明白一个面试官经常会问到的问题。
问题:派生类的Static方法,默认构造方法,和派生方法,父类和子类的加载顺序是什么?

搞明白这个问题,你的疑问就迎刃而解了。
sirnuo 2012-09-17
  • 打赏
  • 举报
回复
虚拟机初始化一个对象时,是先初始化父类,再初始化自身的。
在执行类的构造函数之前,是先初始化类的成员变量的。

所以,去掉注视之后,初始化顺序是这样的:
先初始化父类 X();
在初始化X时,先构造成员变量Y; 输出Y
然后,执行X的构造函数;输出X
然后,初始化Z自身的成员变量Y;输入Y
最后,执行Z的构造函数;输出Z

在类的内部,变量定义的先后顺序决定了初始化的顺序。即使变量定义散布于方法定义之间,它们仍旧在任何方法(包括构造器)被调用之前得到初始化。
nmyangym 2012-09-16
  • 打赏
  • 举报
回复
注释去掉后,在追溯完父类后,回到子类Z继续初始化,在执行构造函数前先要给y显示赋值,即执行Y y = new Y(); 这时输出一个Y. 最后执行构造函数,输出Z.
看看这个:
http://wenwen.soso.com/z/q191435823.htm
杀手 2012-09-16
  • 打赏
  • 举报
回复
程序首先加载类Z,X,之后从父类开始初始化。Y b = new Y();开始加载类Y,并初始化Y,调用Y构造函数,之后开始运行X的构造函数,然后开始初始化Z,Y y = new Y();再次调用Y的构造函数。之后调用Z的构造函数

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧