代码展示
请运行下面代码,查看运行结果,并带着问题,尝试第二次debug程序。
class A {private static int numA;private int numA2;static {System.out.println("A的静态字段 : " + numA);System.out.println("A的静态代码块");}{System.out.println("A的成员变量 : " + numA2);System.out.println("A的非静态代码块");}public A() {System.out.println("A的构造器");}
}class B extends A {private static int numB;private int numB2;static {System.out.println("B的静态字段 : " + numB);System.out.println("B的静态代码块");}{System.out.println("B的成员变量 : " + numB2);System.out.println("B的非静态代码块");}public B() {System.out.println("B的构造器");}
}public class Box {public static void main(String[] args) {A ab = new B();System.out.println("---");ab = new B();}
}
执行结果:
结论
由此,可以看出类中各成员初始化的顺序是:
父类的静态字段——>父类静态代码块——>子类静态字段——>子类静态代码块——>
父类成员变量(非静态字段)——>父类非静态代码块——>父类构造器——>子类成员变量——>子类非静态代码块——>子类构造器
另外,在静态代码块中不能访问成员变量,想想这是为什么?它是否与成员的初始化顺序有必然的联系?
有参构造的执行情况
面试的时候遇到了这样一个问题:
class A {private static int numA;private int numA2;static {System.out.println("A的静态字段 : " + numA);System.out.println("A的静态代码块");}{System.out.println("A的成员变量 : " + numA2);System.out.println("A的非静态代码块");}public A() {System.out.println("A的构造器");}public A(int n) {System.out.println("A的有参构造");this.numA2 = n;}
}class B extends A {private static int numB;private int numB2;static {System.out.println("B的静态字段 : " + numB);System.out.println("B的静态代码块");}{System.out.println("B的成员变量 : " + numB2);System.out.println("B的非静态代码块");}public B() {System.out.println("B的构造器");}public B(int n) {System.out.println("B的有参构造");this.numB2 = n;}
}public class ClassLoad {public static void main(String[] args) {B anotherB = new B(1);// 思考有参构造的输出结果}
}
如上代码,当调用了子类B的有参构造时,父类的构造器先执行肯定是确定无疑,但是是执行哪个构造器呢?
执行结果如下:
执行结果中可以看到,父类A依然是执行了无参构造,也就是说,如果子类构造器中未显式指定父类构造器,那么将会默认执行父类的无参构造,此时,如果你重载了一个父类的有参构造而没有指定无参构造,那么编译将不会通过!!
例如错误代码如下: