Java 中的靜態與實例初始化程序塊
一、概述
在本教程中,我們將學習靜態塊和實例初始化塊的概念。我們還將檢查類構造函數和初始化塊的差異和執行順序。
2. 靜態塊
在 Java 中,靜態塊在對像初始化之前執行代碼。靜態塊是帶有static
關鍵字的代碼塊:
static {
// definition of the static block
}
靜態初始化塊或靜態初始化塊或靜態子句是靜態塊的其他名稱。靜態塊代碼在類加載期間只執行一次。靜態塊總是在 Java 中的main()
方法之前首先執行,因為編譯器在類加載時和對象創建之前將它們存儲在內存中。
一個類可以有多個靜態塊,它們將按照它們在類中出現的順序執行:
public class StaticBlockExample {
static {
System.out.println("static block 1");
}
static {
System.out.println("static block 2");
}
public static void main(String[] args) {
System.out.println("Main Method");
}
}
上述代碼片段的輸出是:
static block 1
static block 2
Main Method
在這裡,編譯器首先執行所有的靜態塊,在完成靜態塊執行後,它會調用main()
方法。 Java 編譯器確保靜態初始化塊的執行順序與它們在源代碼中出現的順序相同。
父類的靜態塊首先執行,因為編譯器在子類之前加載父類。
奇怪的是,在 Java 1.7 之前,並不是每個 Java 應用程序都必須使用 main() 方法,因此所有代碼都可以寫在靜態塊中。但是,從 Java 1.7 開始,main() 方法是強制性的。
3. 實例初始化塊
顧名思義,實例初始化塊的目的是初始化實例數據成員。
實例初始化程序塊看起來就像靜態初始化程序塊,但沒有static
關鍵字:
{
// definition of the Instance initialization block
}
靜態初始化塊總是在實例初始化塊之前執行,因為靜態塊在類加載時運行。但是,實例塊在實例創建時運行。 Java 編譯器將初始化程序塊複製到每個構造函數中。因此,多個構造函數可以使用這種方法來共享一個代碼塊:
public class InstanceBlockExample {
{
System.out.println("Instance initializer block 1");
}
{
System.out.println("Instance initializer block 2");
}
public InstanceBlockExample() {
System.out.println("Class constructor");
}
public static void main(String[] args) {
InstanceBlockExample iib = new InstanceBlockExample();
System.out.println("Main Method");
}
}
因此,在這種情況下,上述代碼的輸出將是:
Instance initializer block 1
Instance initializer block 2
Class constructor
Main Method
實例初始化程序塊在每次構造函數調用期間執行,因為編譯器將初始化程序塊複製到構造函數本身中。
編譯器在執行當前類的實例塊之前執行父類的實例塊。編譯器通過super(),
實例塊在構造函數調用時執行。
4. 靜態初始化塊和實例初始化塊的區別
靜態塊 | 實例初始化程序塊 |
它在類加載期間執行 | 它在類實例化期間執行 |
它只能使用靜態變量 | 它可以使用靜態或非靜態(實例變量)。 |
不能用這個 | 可以用這個 |
當類加載到內存中時,它在程序的整個執行過程中只執行一次 | 每當調用構造函數時,它可以運行多次 |
5. 結論
在本教程中,我們了解到編譯器在類加載期間執行靜態塊。靜態塊可用於初始化靜態變量或調用靜態方法。但是,每次創建類的實例時都會執行一個實例塊,它可用於初始化實例數據成員。
此外,可以在 GitHub 上找到本文的完整代碼示例。