输出结果应该是:DECAHFICAHGJ。
分析如下:
一般Java类的初始化顺序是(参考自引用链接):
1、父类static静态成员和静态代码块,只初始化一次;
2、子类static静态成员和静态代码块,只初始化一次;
3、父类普通成员和非static静态代码块;
4、父类构造函数;
5、子类普通成员变量和非static静态代码块;
6、子类构造函数;
而在这个题目中的初始化顺序具体是:
1、父类的静态代码块 ,输出“D”;
2、子类静态代码块,输出“E”;
3、父类非静态代码块,输出“C”;
4、父类无参的构造器,因为子类没有指定调用哪个父类构造器,就默认调用父类无参的构造器,输出“A”;
5、子类非静态代码块,输出“H”;
6、子类无参构造器,输出“F”;
7、main方法调用无参子类构造器的后面一行,输出'“I”;
8、再次执行父类非静态代码块,静态代码块已执行一次,就不会再执行,所以轮到父类非静态代码块,输出“C”;
9、再次执行父类无参的构造器,同样因为子类没有指定调用哪个父类构造器,就默认调用父类无参的构造器,输出“A”;
10、再次执行子类非静态代码块,输出“H”;
11、调用子类有参的构造器,输“G”;
12、同样,main方法有参的子类构造器调用完,执行其后的一行,最后输出“J”。
所以最后总的输出就是:DECAHFICAHGJ。
测试如下:
参考资料:
Java 编程思想(第4版)第96页、第159页。(此书已有更新的版本)
class CarA{
// 无参TrunkA 4、父类无参构造函数
// 有参TrunkA 9、父类无参构造函数,子类如果没有指定调用父类哪个构造器,默认调用无参的父类构造器
CarA(){
System.out.print("A");
}
CarA(int a){
System.out.print("B");
}
// 无参TrunkA 3、父类普通成员变量或非static块
// 有参TrunkA 8、父类普通成员变量或非static块
{
System.out.print("C");
}
static{ // 无参TrunkA 1、首先调用父类static调用的静态成员或静态代码,这里只执行一次
System.out.print("D");
}
}
class TrunkA extends CarA{
static { // 无参TrunkA 2、子类static修改的静态成员或静态代码,这里只执行一次
System.out.print("E");
}
TrunkA(){ // 无参TrunkA 6、子类无参构造函数
//super(1);
System.out.print("F");
}
TrunkA(int a){ // 有参TrunkA 11、子类有参构造器
//super(1);
System.out.print("G");
}
// 无参TrunkA 5、子类普通成员或非静态块
// 有参TrunkA 10、子类普通成员或非静态块
{
System.out.print("H");
}
}
public class InitTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
TrunkA s1 = new TrunkA();
System.out.print("I");//7 、执行完上一行的代码,这里输出"I"
TrunkA s2 = new TrunkA(3);
System.out.print("J"); // 12、执行完上一行代码,这里最后输出"J"结束
}
}