歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Java 類成員的初始化順序

Java 類成員的初始化順序

日期:2017/3/1 9:05:47   编辑:Linux編程

前言:開發中碰到一個Java文件中有很多的成員變量,包括靜態和非靜態的,還有很多的初始化方法,很好奇這些成員的初始化順序,在這裡作個研究。

1 無繼承情況下的Java初始化順序:

class Sample {

Sample(String s) {

System.out.println(s);

}

Sample() {

System.out.println("Sample默認構造函數被調用");

}

}

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默認構造函數被調用");

}

}

//主函數

public static void main(String str[]) {

Test a=new 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成員初始化");

}

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初始化順序為:

a 繼承體系的所有靜態成員初始化(先父類,後子類)

b父類初始化完成(普通成員的初始化-->構造函數的調用)

c 子類初始化(普通成員-->構造函數)

Java初始化順序如圖:

Copyright © Linux教程網 All Rights Reserved