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
子類構造函數
結論:
當存在繼承關係時,初始化順序爲:
- 父類(靜態變量、靜態語句塊)
- 子類(靜態變量、靜態語句塊)
- 父類(實例變量、普通語句塊)
- 父類(構造函數)
- 子類(實例變量、普通語句塊)
- 子類(構造函數)