对于java初学者,肯定对java的初始化顺序比较迷惑,而且很多java面试中也会考察java初始化顺序这个知识点,就此整理一下.
一.非继承情况
首先说说非继承的情况,对于非继承的情况,初始化顺序为:(静态变量,静态初始化块)>(变量,初始化块)>构造器.我们来看一个例子:
public class InitialOrderTest {
//静态变量
public static String staticField="静态变量";
//变量
public String field="变量";
//静态初始化块
static{
System.out.println(staticField);
System.out.println("静态初始化块");
}
//初始化块
{
System.out.println(field);
System.out.println("初始化块");
}
//构造器
public InitialOrderTest(){
System.out.println("构造器");
}
public static void main(String[] args) {
new InitialOrderTest();
}
}
这个例子的输出结果为:
静态变量
静态初始化块
变量
初始化块
构造器
二.包含继承的情况
对于包含继承的情况,初始化顺序为:父类(静态变量,静态初始化块)>子类(静态变量,静态初始化块)>父类(变量,初始化块)>父类构造器>子类(变量,初始化块)>子类构造器
我们同样来看一个例子:
class Parent{
//静态变量
public static String p_StaticField="父类-静态变量";
//变量
public String p_Field="父类-变量";
//静态初始化块
static{
System.out.println(p_StaticField);
System.out.println("父类-静态初始化块");
}
//初始化块
{
System.out.println(p_Field);
System.out.println("父类-初始化块");
}
//构造器
public Parent(){
System.out.println("父类-构造器");
}
}
public class SubClass extends Parent{
//静态变量
public static String s_StaticField="子类-静态变量";
//变量
public String s_Field="子类-变量";
//静态初始化块
static{
System.out.println(s_StaticField);
System.out.println("子类-静态初始化块");
}
//初始化块
{
System.out.println(s_Field);
System.out.println("子类-初始化块");
}
//构造器
public SubClass() {
System.out.println("子类-构造器");
}
public static void main(String[] args) {
new SubClass();
}
}
这个例子的结果为:
父类-静态变量
父类-静态初始化块
子类-静态变量
子类-静态初始化块
父类-变量
父类-初始化块
父类-构造器
子类-变量
子类-初始化块
子类-构造器
三.变量和初始化块之间的顺序
上面两个例子可能会给我们造成一个误解,就是静态变量先于静态初始化块,变量先于初始化块被初始化,实际上并不是这样的,实际的初始化顺序是由他们在代码中出现的先后顺序决定的.
最后总结一下初始化顺序:先静态,后非静态;先父类后子类;先变量,后方法(包括构造方法).
参考资料: