1、Java無繼承情況下的初始化順序:
class Sample
{
Sample(String s)
{
System.out.println(s);
}
Sample()
{
System.out.println("Sample預設建構函式被調用");
}
//主函數
public static void main(String str[])
{
Test a=new Test();
}
}
class Test{
static Sample sam=new Sample("靜態成員sam初始化");
Sample sam1=new Sample("sam1成員初始化");
static{
System.out.println("static塊執行");
if(sam==null)System.out.println("sam is null");
sam=new Sample("靜態塊內初始化sam成員變數");
}
Test()
{
System.out.println("Test預設建構函式被調用");
}
}
輸出結果為: 靜態成員sam初始化 -----靜態成員初始化 static塊執行 -----靜態塊被執行 靜態塊內初始化sam成員變數 ----靜態塊執行 sam1成員初始化 -----普通成員初始化 Test預設建構函式被調用 -----建構函式執行
由此可以得出結論: a 靜態成員變數首先初始化(注意,Static可以看做一個靜態成員,其執行順序和其在類中申明的順序有關) b 普通成員初始化 c 執行建構函式。
對於靜態成員(static塊可以看成普通的一個靜態成員,其並不一定在類初始化時首先執行)和普通成員,其初始化順序只與其在類定義中的順序有關,和其他因素無關。 例如下面的例子:
class Test{ static{ System.out.println("static 塊 1 執行"); } static Sample staticSam1=new Sample("靜態成員staticSam1初始化"); Sample sam1=new Sample("sam1成員初始化"); static Sample staticSam2=new Sample("靜態成員staticSam2初始化"); static{ System.out.println("static 塊 2 執行"); } Test() { System.out.println("Test預設建構函式被調用"); } Sample sam2=new Sample("sam2成員初始化");
}
則結果為: static 塊 1 執行 靜態成員staticSam1初始化 靜態成員staticSam2初始化 static 塊 2 執行 --------靜態成員 sam1成員初始化 sam2成員初始化 --------普通成員 Test預設建構函式被調用 --------建構函式
2、Java繼承情況下的初始化順序:
class Test{
static{
System.out.println("父類static 塊 1 執行");
}
static Sample staticSam1=new Sample("父類 靜態成員staticSam1初始化");
Sample sam1=new Sample("父類 sam1成員初始化");
static Sample staticSam2=new Sample("父類 靜態成員staticSam2初始化");
static{
System.out.println("父類 static 塊 2 執行");
}
Test()
{
System.out.println("父類 Test預設建構函式被調用");
}
Sample sam2=new Sample("父類 sam2成員初始化");
public static void main(String str[]){
TestSub a=new TestSub();
}
}
class TestSub extends Test
{
static Sample staticSamSub=new Sample("子類 靜態成員staticSamSub初始化");
TestSub()
{
System.out.println("子類 TestSub 預設建構函式被調用");
}
Sample sam1=new Sample("子類 sam1成員初始化");
static Sample staticSamSub1=new Sample("子類 靜態成員staticSamSub1初始化");
static{System.out.println("子類 static 塊 執行");}
Sample sam2=new Sample("子類 sam2成員初始化");
}
執行結果: 父類 static 塊 1 執行 父類 靜態成員staticSam1初始化 父類 靜態成員staticSam2初始化 父類 static 塊 2 執行 --------父類靜態成員初始化 子類 靜態成員staticSamSub初始化 子類 靜態成員staticSamSub1初始化 子類 static 塊 執行 -------子類靜態成員初始化 父類 sam1成員初始化 父類 sam2成員初始化 父類 Test預設建構函式被調用 -------父類普通成員初始化和建構函式執行 子類 sam1成員初始化 子類 sam2成員初始化 子類 TestSub 預設建構函式被調用 -------父類普通成員初始化和建構函式執行
由此得出Java初始化順序結論: 1 繼承體系的所有靜態成員初始化(先父類,後子類) 2 父類初始化完成(普通成員的初始化-->建構函式的調用) 3 子類初始化(普通成員-->建構函式)