0 前言
本文通过拆分类似概念之间的初始化顺序,帮助大家彻底记住初始化的顺序
1. 父类和子类间的初始化顺序
示例代码:
public class Father {
public Father() {
System.out.println("father");
}
public static void main(String[] args) {
grandson grandson = new grandson();
}
}
class son extends Father {
public son() {
System.out.println("son");
}
}
class grandson extends son{
public grandson() {
System.out.println("grandson");
}
}
输出结果:
father
son
grandson
结论:
当存在父类时,先初始化父类构造函数,如果父类还有父类,再初始父类的父类构造函数,依次类推。
2. 构造函数、静态变量和实例变量的初始化顺序
示例代码:
public class Var {
public Var() {
printInit("structor");
}
public int j = printInit("Init");
public static int i = printInit("static Init");
static int printInit(String s) {
System.out.println(s);
return 0;
}
public static void main(String[] args) {
Var var = new Var();
}
}
输出结果:
static Init
Init
structor
结论:
静态变量 -> 实例变量 -> 结构体
3. 静态语句块和静态变量的初始化顺序
示例代码:
public class StaticCompare {
public static int i = 1;
static {
i = 2;
j = 2;
}
public static int j = 1;
public static void main(String[] args) {
System.out.println("i = " + StaticCompare.i);
System.out.println("j = " + StaticCompare.j);
}
}
输出结果:
i = 2
j = 1
结论:
静态语句块和静态变量按代码顺序执行,谁在前面谁先执行
4. 普通语句块和实例变量的初始化顺序
示例代码:
public class VarCompare {
public int i = 1;
{
i = 2;
j = 2;
}
public int j = 1;
public static void main(String[] args) {
VarCompare varCompare = new VarCompare();
System.out.println("i = " + varCompare.i);
System.out.println("j = " + varCompare.j);
}
}
输出结果:
i = 2
j = 1
结论:
普通语句块和实例变量按代码顺序执行,谁在前面谁先执行
5. 总结
先做个小结,现在已经测试的顺序是:
静态变量(静态语句块) -> 实例变量(普通语句块) -> 构造函数
父类构造函数 -> 子类构造函数
接下来需要知道的是,当它们同时存在,是什么顺序?
5. 全部的初始化顺序
示例代码:
public class AllSequence extends father{
public static int i = printInit("子类静态变量 i");
public int j = printInit("子类实例变量 j");
AllSequence(){
System.out.println("子类构造函数");
}
public static void main(String[] args) {
AllSequence allSequence = new AllSequence();
}
}
class father {
public static int i = printInit("父类静态变量 i");
public int j = printInit("父类实例变量 j");
father(){
System.out.println("父类构造函数");
}
static int printInit(String s) {
System.out.println(s);
return 1;
}
}
输出结果:
父类静态变量 i
子类静态变量 i
父类实例变量 j
父类构造函数
子类实例变量 j
子类构造函数
结论:
当存在继承关系时,初始化顺序为:
- 父类(静态变量、静态语句块)
- 子类(静态变量、静态语句块)
- 父类(实例变量、普通语句块)
- 父类(构造函数)
- 子类(实例变量、普通语句块)
- 子类(构造函数)