在 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();
}
}
父類--靜態變量
父類--靜態初始化塊
子類--靜態變量
子類--靜態初始化塊
父類--變量
父類--初始化塊
父類--構造器
子類--變量
子類--初始化塊
子類--構造器
靜態變量與靜態塊、實例變量與實例塊,均按其在類中出現的先後順序執行。
public class TestOrder {
public static TestA a = new TestA();
public TestC c = new TestC();
public static TestB b = new TestB();
public TestOrder() {
System.out.println("in constract");
}
static {
System.out.println("靜態初始化塊");
}
public static void main(String[] args) {
new TestOrder();
}
}
class TestA { public TestA() { System.out.println("Test--A"); } }
class TestB { public TestB() { System.out.println("Test--B"); } }
class TestC { public TestC() { System.out.println("Test--C"); } }
Test--A
Test--B
靜態初始化塊
Test--C
in constract
先靜後動,先父後子,從上到下,先變量後構造