1、完整的初始化顺序(含继承)
1、父类的静态初始化
父类静态变量默认值 → 父类静态变量显式赋值 + 父类静态代码块(按代码顺序执行)。
2、子类的静态初始化
子类静态变量默认值 → 子类静态变量显式赋值 + 子类静态代码块(按代码顺序执行)。
3、父类的实例初始化
父类实例变量默认值 → 父类实例变量显式赋值 + 父类实例代码块(按代码顺序执行)→ 父类构造函数。
4、子类的实例初始化
子类实例变量默认值 → 子类实例变量显式赋值 + 子类实例代码块(按代码顺序执行)→ 子类构造函数。
2、代码示例
class Parent {
// 父类静态变量
private static String parentStaticField = initParentStaticField();
// 父类静态代码块
static {
System.out.println("父类静态代码块执行");
}
// 父类实例变量
private String parentInstanceField = initParentInstanceField();
// 父类实例代码块
{
System.out.println("父类实例代码块执行");
}
// 父类构造函数
public Parent() {
System.out.println("父类构造函数执行");
}
// 父类初始化方法
private static String initParentStaticField() {
System.out.println("父类静态变量赋值");
return "parentStatic";
}
private String initParentInstanceField() {
System.out.println("父类实例变量赋值");
return "parentInstance";
}
}
public class Test extends Parent {
// 子类静态变量
private static String staticField = initStaticField();
// 子类静态代码块
static {
System.out.println("子类静态代码块执行");
}
// 子类实例变量
private String instanceField = initInstanceField();
// 子类实例代码块
{
System.out.println("子类实例代码块执行");
}
// 子类构造函数
public Test() {
System.out.println("子类构造函数执行");
}
// 子类初始化方法
private static String initStaticField() {
System.out.println("子类静态变量赋值");
return "static";
}
private String initInstanceField() {
System.out.println("子类实例变量赋值");
return "instance";
}
public static void main(String[] args) {
new Test();
}
}
执行结果:
父类静态变量赋值 // 父类静态初始化开始
父类静态代码块执行 // 父类静态初始化完成
子类静态变量赋值 // 子类静态初始化开始
子类静态代码块执行 // 子类静态初始化完成
父类实例变量赋值 // 父类实例初始化开始
父类实例代码块执行
父类构造函数执行 // 父类实例初始化完成
子类实例变量赋值 // 子类实例初始化开始
子类实例代码块执行
子类构造函数执行 // 子类实例初始化完成
分析:
可知通过继承时候,当加载子类时候会优先加载父类,等父类全部加载完毕才会进行子类的加载,静态变量特殊,如果