解决方案 »

  1.   

    1. 第4步分析有问题:Yy类有静态成员static Zz zz=new Zz();所以会初始化该成员,所以第一条输出是Zz constructor。
    2. 加载一个类时,如果此类有父类,则会在进行static成员初始化操作之前,加载父类,因此初始化顺序是父类的static成员首先进行;之所以先加载父类再进行自身static成员的初始化,在于父类其实是子类的一部分(可以理解为子类的类文件=自身的类文件+父类的类文件),因此子类要加载完全自身的信息,就必须把父类的文件也加载进来,再进行自身的初始化;
      

  2.   

    关于第6点,当new一个类的对象时,
    1. 首先为该类分配堆内存,该对内存空间会被清零,所以该类的基本类型成员会被设置成默认值,引用被设置为Null;
    2. 其次,若该类的成员在定义时有初始化行为,如Cc类中的Bb b = new Bb();则会在调用自身构造函数之前进行这些成员的初始化,所以输出Bb constructor。有问题可以再交流交流。
      

  3.   


    谢谢,你的意思我完全明白了。我本来在原来在Yy类中没有static Zz.后来加上去的,但是第4部这句话忘改了。
      

  4.   

    当new一个对象的,是为这个类的对象(实例)分配内存空间对吧?如果类的成员在定义时有初始化行为,会在构造函数调用之前初始化成员,这点我能理解。
    我不理解的就是super(i),这种显示调用究竟有什么用?这句话明明放在了到处类构造器中的第一句,那么必然是先要调用基类的构造器才能执行super(i)啊,但是这就和输出的结果矛盾了
      

  5.   

    初始化顺序:先父类静态代码块--->再子类静态代码块-->默认初始化--->父类构造-->显示初始化-->构造代码块-->子类自身特有初始化楼主记住这个顺序然后能就拿着分析就行了!下面试着分析一下楼主的程序:从子类开始,用到哪个加载哪个,有继承关系,先加载父类,然后加载子类,而静态是随着类的加载而加载的,所以静态成员会最先加载,而又因为A继承与Y,所以先加载完Y类,所以静态成员Z随着Y类最先加载完成,所以最先调用Z构造,而后加载A类,B静态成员随着A类加载而加载,所以紧接着调用了B构造,加载完类后,开始从父类一致往下执行构造,所以根据继承关系,C继承于A,A继承与Y,那么会先执行Y构造,但是执行Y自身构造方法之前,会先执行Y类中的成员显示初始化,那么,这时候第三个调用的就是X类构造了,执行完显示初始化后,就执行构造代码块,但是构造代码块没有,所以直接执行第四个构造,就是Y类自身构造了,整个Y类构造完之后回到A类,根据对Y类的分析,同理可以直到,先执行显示初始化,所以执行了X构造,然后就A构造,A类初始化完后就会执行C类自身的了,又同理,先执行了B类构造,然后再试C类自身的构造,所以你的代码构造函数执行的顺序是:
    Z
    B
    X
    Y
    X
    A
    B
    C
    楼主明白了么?
    还有,建议楼主现在没什么基础,不要去看thinking in java,个人觉得不适合初学者,由于外国人写的书,翻译过来,语法上的逻辑理解比较困,所以看起来可能会比较麻烦,建议先买一些简单粗浅的书看,或者下视频学更好啦