遵循老师的指引,我运行了以下代码:
package movehands3_1;
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 msg)
{
//通过this调用同一类中重载的构造器
this();
System.out.println("Mid的带参数构造器,其参数值:" + msg);
}
}
class Leaf extends Mid
{
static
{
System.out.println("Leaf的静态初始化块");
}
{
System.out.println("Leaf的普通初始化块");
}
public Leaf()
{
//通过super调用父类中有一个字符串参数的构造器
super("Java初始化顺序演示");
System.out.println("执行Leaf的构造器");
}
}
public class TestStaticInitializeBlock
{
public static void main(String[] args)
{
new Leaf();
}
}
其运行结果为——
Root的静态初始化块
Mid的静态初始化块
Leaf的静态初始化块
Root的普通初始化块
Root的无参数的构造器
Mid的普通初始化块
Mid的无参数的构造器
Mid的带参数构造器,其参数值:Java初始化顺序演示
Leaf的普通初始化块
执行Leaf的构造器
我们发现被static修饰的静态初始化块的执行是排在普通字段和构造函数的前面的,而后两者的顺序由代码顺序决定属于同一层次,即在同一个类或者按如上方式继承自同一基类时,程序会按照从祖到孙的顺序,先静态初始化块,再按照每类中三种“普通的初”始化方法的顺序来执行。
静态初始化块的执行具有最高优先级,子类的创建会导致父类静态初始化块的运行,因此出现了从祖到孙的静态初始化顺序,同理,优先级较低的普通初始化块和构造函数因为处于同一优先级,所以它们的执行成对出现,也因为子类的创建会调用父类代码,所以导致”普通初始化块\n构造器\n“按照Root、Mid、Leaf的顺序依次成对打印。