我们都知道java中不但有构造器,还有初始化块和静态初始化块的概念,今天我们就来看看他们之间的执行顺序是怎样的。
我们来看一个例子:
package test;
class Root {
static {
System.out.println("Root的静态初始化块");
}
{
System.out.println("Root的普通初始化块");
}
public Root() {
System.out.println("Root的无参构造");
}
}
class Mid extends Root {
static {
System.out.println("Mid的静态初始化块");
}
{
System.out.println("Mid的普通初始化块");
}
public Mid() {
System.out.println("Mid的无参构造");
}
public Mid(String name) {
this();
System.out.println("Mid的带参构造器" + name);
}
}
class Leaf extends Mid {
static {
System.out.println("Leaf的静态初始化块");
}
{
System.out.println("Leaf的普通初始化块");
}
public Leaf() {
super("疯狂java讲义");
System.out.println("Leaf的无参构造");
}
}
public class Test {
public static void main(String[] args) {
new Leaf();
new Leaf();
}
}
该段代码的执行结果如下:
从代码运行的结果来看,我们可以知道三点:
1.类的初始化阶段,先执行最顶层的父类的静态初始化块,然后依次向下执行,直到执行当前类的静态初始化块
2.对象初始化阶段,先执行最顶层父类的初始化块,最顶层父类的构造器,然后依次向下,直到执行当前类的初始化块当前类的构造器。
3.当第二次创建对象时,由于这些类在第一次创建对象时已经被加载过了,因此静态初始化块只会执行一次。
总结一下三者的执行顺序:
1.父类的静态初始化块
2.子类的静态初始化块
3.父类的初始化块
4.父类的构造函数
5.子类的初始化块
6.子类的构造函数