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();
    }
}
两个问题请教大家:1.运行结果;2.分析结果.

解决方案 »

  1.   

    YXYZ   就是初始化顺序的问题
    super()  成员变量初始化  构造器体
      

  2.   

    YXYZ
    这个题考得是子类初始化顺序以及属性和构造初始化顺序。
    在new一个Z的时候,由于它有父类,因此先初始化父类X(这个很好理解,既然子类继承父类,那当然是父类给有东西才能继承,因此为了防止子类在初始化时用到父类的东西,自然给先把父类初始化出来。)于是到X的内部,它有一个属性还有一个构造,那么先初始化哪个呢?通常在构造里我们都会对类的属性进行一些操作(这点你可以看看现成代码,很多都这样),如果构造执行在先那么在操作属性时,属性还没初始化怎么行。所以要先初始化属性Y。于是又转到Y里,Y比较简单没属性,构造里输出“Y”即可,然后在执行X的构造输出“X”,这时候父类X初始化完了,再接着初始化Z,还是先初始化属性,那么输出“Y”,然后再输出构造里的“Z”。
    实际上这道题是简化很多的。因为它没有考到静态属性(类属性)以及程序块及静态程序块。
    我把这个题改一下,你运行一下对照结果,应该会有些收获的。
    public class Z extends X{
        
        static{ //静态代码块
            System.out.println("我是子类的静态代码块,除了父类静态代码块和静态属性(类变量)我是最先执行的"); 
        }
        static C c= new C(); //静态属性
        
        Y2 y=new Y2();
        
        { System.out.println("我是子类初始化块,我的优先级和非静态属性一样,我们之间的顺序以代码顺序为准"); } //初始化块
        
        
        Z(){System.out.println("我是子类构造函数");}
        
        public static void main(String[] args){
            new Z();
        }   
    }
    class X{
        
        static{System.out.println("我是父类的静态代码块,我是最先执行的"); }  //静态代码块       
        
        static C2 c= new C2();  //静态属性     
        
        { System.out.println("我是父类初始化块,我的优先级和非静态属性一样,我们之间的顺序以代码顺序为准"); } //初始化块
        
        
        Y b=new Y();  //非静态属性    X(){System.out.println("我是父类构造函数");}
    }
    class Y{
        Y(){System.out.println("我是父类非静态属性,和具体的类实例相关,我可能在初始化块前执行也可能在其后");}
    }class Y2{
        Y2(){System.out.println("我是子类非静态属性,和具体的类实例相关,我可能在初始化块前执行也可能在其后");}
    }class C{
        C(){System.out.println("我是子类的一个静态属性(类变量),我和之前的初始化过程都是针对类的,与实例无关");}
    }class C2{
        C2(){System.out.println("我是父类一个静态属性(类变量),我比子类的静态代码块执行的还早");}
    }
      

  3.   

    YXYZ“实例化”一个类时先去把父类实例话,然后把成员变量初始化,然后再构造函数。所以new Z()时先去实例化Z的父类X。在实例化X时,X没有父类,所以初始化成员Y,这时打印第一个Y,然后调用X的构造函数,这时打印X,
    Z的父类实例完后就实例化Z的成员变量,只有一个成员变量Y,这时打印第二个Y,然后最后调用Z的构造函数,这时打印Z
      

  4.   

    实例化一个类时,首先去实例化父类,再去实例化子类,类中的成员变量和构造函数,首先去初始化其成员变量,然后再执行构造函数。你可以做一下测试:
    class X {
            String str = this.getStr();
    Y b = new Y();
    X() {
    System.out.print("X ");
    }
    String getStr(){
    System.out.println("我要初始化成员变量");
    return "0000";
    }
    }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) {
    System.out.println("---------");
    new Z();
    }
    }