写在前面的话
之前有个认识的朋友出去面试,遇到了一个类初始化和实例初始化的问题,本人也试着做,但是做错了。一时茫然,好歹有几年的开发经验了,确连根本的基础题都不会做了真是万分羞愧,特地记录一下,巩固一下基础。
面试题
首先有一个Father类:
public class Father {
private int i = test();
private static int j = method();
static {
System.out.println("(1)");
}
Father() {
System.out.println("(2)");
}
{
System.out.println("(3)");
}
public int test() {
System.out.println("(4)");
return 1;
}
public static int method() {
System.out.println("(5)");
return 1;
}
}
然后有个Son类:
public class Son extends Father {
private int i = test();
private static int j = method();
static {
System.out.println("(6)");
}
Son() {
System.out.println("(7)");
}
{
System.out.println("(8)");
}
public int test() {
System.out.println("(9)");
return 1;
}
public static int method() {
System.out.println("(10)");
return 1;
}
}
测试类:
public static void main(String[] args) {
Son son = new Son();
System.out.println();
Son son1 = new Son();
}
在做这个题之前,需要知道类的初始化和实例化的整个流程是如下:
- 初始化父类的静态成员
- 初始化父类的静态代码块
- 初始化子类的静态成员
- 初始化子类的静态代码块
- 初始化父类的非静态成员
- 初始化父类的非静态代码块
- 初始化父类的构造方法
- 初始化子类的非静态成员
- 初始化子类的非静态代码块
- 初始化子类的构造方法
需要注意的是因为类只会被加载一次,所以静态方法和静态代码块只会执行一次。
所以执行结果是:(5)(1)(10)(6)(9)(3)(2)(9)(8)(7)。
需要注意的是第五步时候父类的test方法被重写
,所以会调用子类的test方法,所以这里输出的是9而不是4,如果将父类的test方法更改方法名为test1,此时就直接输出父亲test1的4。
综上所述
记住,面试有可能会标出一些语句的,让你选择这些语句的执行顺序。不过只要知道原理,就没什么难的了。