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的输出先后顺序不一样了,谁能帮我从底层对象创建方面分析透彻一点,有点搞不清。

解决方案 »

  1.   

    程序首先加载类Z,X,之后从父类开始初始化。Y b = new Y();开始加载类Y,并初始化Y,调用Y构造函数,之后开始运行X的构造函数,然后开始初始化Z,Y y = new Y();再次调用Y的构造函数。之后调用Z的构造函数
      

  2.   

    注释去掉后,在追溯完父类后,回到子类Z继续初始化,在执行构造函数前先要给y显示赋值,即执行Y y = new Y(); 这时输出一个Y. 最后执行构造函数,输出Z.
    看看这个:
    http://wenwen.soso.com/z/q191435823.htm
      

  3.   

    第一步new Z();使用Z的构造方法的时候首先要调用他的父类X的构造方法 只有当X构造出来了之后才能newZ的对象。这样说 明白了吗?去看看super()
      

  4.   

    从你的提问看,你已经知道为什么第一次输出的是YXZ了;
    第二次输出的YXYZ,与第一次相比,输出顺序并没有变化,XZ之间多了一个Y,是由于Y y = new Y();在Z()之前构造,但又必须在父类构造完成之后。
      

  5.   

    lz已经搞清楚 XYZ 了 多了个Y就不懂了? 后者比前者好理解的多
      

  6.   

    虚拟机初始化一个对象时,是先初始化父类,再初始化自身的。
    在执行类的构造函数之前,是先初始化类的成员变量的。所以,去掉注视之后,初始化顺序是这样的:
    先初始化父类 X();
    在初始化X时,先构造成员变量Y; 输出Y
    然后,执行X的构造函数;输出X
    然后,初始化Z自身的成员变量Y;输入Y
    最后,执行Z的构造函数;输出Z在类的内部,变量定义的先后顺序决定了初始化的顺序。即使变量定义散布于方法定义之间,它们仍旧在任何方法(包括构造器)被调用之前得到初始化。
      

  7.   

    楼主,建议你去弄明白一个面试官经常会问到的问题。
    问题:派生类的Static方法,默认构造方法,和派生方法,父类和子类的加载顺序是什么?搞明白这个问题,你的疑问就迎刃而解了。
      

  8.   

    这样你会更清楚一点咯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();
    }
    }