关于第6点,当new一个类的对象时, 1. 首先为该类分配堆内存,该对内存空间会被清零,所以该类的基本类型成员会被设置成默认值,引用被设置为Null; 2. 其次,若该类的成员在定义时有初始化行为,如Cc类中的Bb b = new Bb();则会在调用自身构造函数之前进行这些成员的初始化,所以输出Bb constructor。有问题可以再交流交流。
初始化顺序:先父类静态代码块--->再子类静态代码块-->默认初始化--->父类构造-->显示初始化-->构造代码块-->子类自身特有初始化楼主记住这个顺序然后能就拿着分析就行了!下面试着分析一下楼主的程序:从子类开始,用到哪个加载哪个,有继承关系,先加载父类,然后加载子类,而静态是随着类的加载而加载的,所以静态成员会最先加载,而又因为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,个人觉得不适合初学者,由于外国人写的书,翻译过来,语法上的逻辑理解比较困,所以看起来可能会比较麻烦,建议先买一些简单粗浅的书看,或者下视频学更好啦
2. 加载一个类时,如果此类有父类,则会在进行static成员初始化操作之前,加载父类,因此初始化顺序是父类的static成员首先进行;之所以先加载父类再进行自身static成员的初始化,在于父类其实是子类的一部分(可以理解为子类的类文件=自身的类文件+父类的类文件),因此子类要加载完全自身的信息,就必须把父类的文件也加载进来,再进行自身的初始化;
1. 首先为该类分配堆内存,该对内存空间会被清零,所以该类的基本类型成员会被设置成默认值,引用被设置为Null;
2. 其次,若该类的成员在定义时有初始化行为,如Cc类中的Bb b = new Bb();则会在调用自身构造函数之前进行这些成员的初始化,所以输出Bb constructor。有问题可以再交流交流。
谢谢,你的意思我完全明白了。我本来在原来在Yy类中没有static Zz.后来加上去的,但是第4部这句话忘改了。
我不理解的就是super(i),这种显示调用究竟有什么用?这句话明明放在了到处类构造器中的第一句,那么必然是先要调用基类的构造器才能执行super(i)啊,但是这就和输出的结果矛盾了
Z
B
X
Y
X
A
B
C
楼主明白了么?
还有,建议楼主现在没什么基础,不要去看thinking in java,个人觉得不适合初学者,由于外国人写的书,翻译过来,语法上的逻辑理解比较困,所以看起来可能会比较麻烦,建议先买一些简单粗浅的书看,或者下视频学更好啦