今天突然想起了几年前我碰到的一个 Java 面试题,内容略简单,还是在此记录备忘。不讨论深层次原理,我也不会。
Java 中代码块、静态代码块和构造函数的执行顺序是怎样的?
针对此问题,要考虑父类子类继承关系,考虑多个代码块前后顺序。于是撸上代码
父类:
public class ParentClass {
static {
System.out.println("父类 - 静态 - 代码块1");
}
{
System.out.println("父类 - 普通 - 代码块1");
}
static {
System.out.println("父类 - 静态 - 代码块2");
}
public ParentClass(){
System.out.println("父类 - 构造函数");
}
{
System.out.println("父类 - 普通 - 代码块2");
}
static {
System.out.println("父类 - 静态 - 代码块3");
}
}
子类:
public class SunClass extends ParentClass{
static {
System.out.println("子类 - 静态 - 代码块1");
}
{
System.out.println("子类 - 普通 - 代码块1");
}
static {
System.out.println("子类 - 静态 - 代码块2");
}
public SunClass() {
System.out.println("子类 - 构造函数");
}
{
System.out.println("子类 - 普通 - 代码块2");
}
static {
System.out.println("子类 - 静态 - 代码块3");
}
}
测试类:
public class BlockTest {
public static void main(String[] args){
new ParentClass();
new SunClass();
new SunClass();
}
}
测试结果
1、先只 new 一个父类看看输出结果:
父类 - 静态 - 代码块1
父类 - 静态 - 代码块2
父类 - 静态 - 代码块3
父类 - 普通 - 代码块1
父类 - 普通 - 代码块2
父类 - 构造函数
2、再尝试 new 两个子类试试:
父类 - 静态 - 代码块1
父类 - 静态 - 代码块2
父类 - 静态 - 代码块3
子类 - 静态 - 代码块1
子类 - 静态 - 代码块2
子类 - 静态 - 代码块3
父类 - 普通 - 代码块1
父类 - 普通 - 代码块2
父类 - 构造函数
子类 - 普通 - 代码块1
子类 - 普通 - 代码块2
子类 - 构造函数
父类 - 普通 - 代码块1
父类 - 普通 - 代码块2
父类 - 构造函数
子类 - 普通 - 代码块1
子类 - 普通 - 代码块2
子类 - 构造函数
结论:
由以上两次试验可以得出结论。当 new 一个对象时,该类的 代码块、静态代码块 和 构造函数在父子类之间的执行顺序是:
1、父类 - 静态 - 代码块 (多个同级代码块,按照代码顺序执行;且只在类加载时执行一次)
2、子类 - 静态 - 代码块 (多个同级代码块,按照代码顺序执行;且只在类加载时执行一次)
// 第一次 new
3、父类 - 普通 - 代码块 (多个同级代码块,按照代码顺序执行;在当前类构造函数之前执行;每次 new 时都会执行)
4、父类 - 构造函数
5、子类 - 普通 - 代码块 (多个同级代码块,按照代码顺序执行;在当前类构造函数之前执行;每次 new 时都会执行)
6、子类 - 构造函数
// 第二次 new
7、父类 - 普通 - 代码块 (多个同级代码块,按照代码顺序执行;在当前类构造函数之前执行;每次 new 时都会执行)
8、父类 - 构造函数
9、子类 - 普通 - 代码块 (多个同级代码块,按照代码顺序执行;在当前类构造函数之前执行;每次 new 时都会执行)
10、子类 - 构造函数