1. 程式人生 > >Java中靜態變數和非靜態變數的初始化順序

Java中靜態變數和非靜態變數的初始化順序

 

先看下面的程式:

package c05.net;

class Bowl {
Bowl(int marker) {
System.out.println("Bowl(" + marker + ")");
}

void f1() {
System.out.println("Ok");
}
}

class Cupboard {
Bowl b1 = new Bowl(1);

static Bowl b2 = new Bowl(2);

Cupboard() {
System.out.println("Cupboard()");
}

static Bowl b3 = new Bowl(3);
}

class Table {
Table() {
System.out.println("Table()");
}
Table(String a,int i){
this();
System.out.println("Ok");
}
}

public class Order {
static Cupboard t1 = new Cupboard();

static Table t2;

Bowl t3 = new Bowl(10);

void print() {
t3.f1();
}

public static void main(String[] args) {
System.out.println("Creating new Cupboard() in main");
new Cupboard();
System.out.println("Creating new Cupboard() in main");
Order od = new Order();
od.t3.f1();
Table t4 = new Table("aa",1);
}
}

執行結果:

Bowl(2)
Bowl(3)
Bowl(1)
Cupboard()
Creating new Cupboard() in main
Bowl(1)
Cupboard()
Creating new Cupboard() in main
Bowl(10)
Ok
Table()
Ok

分析:首先程式從public類開始,裝載Order,class,執行static Cupboard t1 = new Cupboard();

由於t1是一個物件引用變數,首先得到初始化,然後轉到Cupboard類的例項中,這時候程式開始初始化

該例項中的變數,按照先static後非static變數初始化的順序原則開始初始化各個變數,此時,

static Bowl b2 = new Bowl(2);

static Bowl b3 = new Bowl(3);

這兩塊先得到初始化

然後    Bowl b1 = new Bowl(1);得到初始化(注意,這是非stataic變數)

然後轉到Cupboard() 建構函式。

此時Cupboard類已經初始化完畢,程式返回到public類中,又發現有 static Table t2;

開始初始化,由於t2只是個宣告的變數,並沒有建立一個Table物件讓它指向,因此不要管這個t2變數。

在public類中,由於此時再沒有static變數可以初始化,那麼程式轉到static方法main中進行,

(注意:Bowl t3 = new Bowl(10); 這一句為什麼得不到初始化,是因為此時沒有建立類Order的例項,所以程式目前還不會初始化該程式碼,至於以後會不會初始化,還要看在main方法中是否會建立Order類的例項,如建立了,則一定初始化,否則不會。)

在main方法中,

System.out.println("Creating new Cupboard() in main");//首先列印該行要輸出的語句

new Cupboard();   //建立了Cupboard類的例項,程式轉到Cupboard中進行變數初始化,此時要注意:    

static變數的初始化,它只能初始化一次,也就是說,如果前面已經初始化過了,那麼此時就不必要再初

始化了,這一點要牢記!!!

System.out.println("Creating new Order() in main");//程式轉入此行列印要輸出的語句

Order od = new Order();//建立Order物件例項,程式轉入例項od中,此時Bowl t3 = new Bowl(10);

這一句的t3會得到初始化,程式轉到Bowl類中進行有關的操作,操作完後返回到main方法中

od.t3.f1();   //呼叫例項t3中的方法f()

Table t4 = new Table("aa",1); //建立Table類的例項,讓t4指向這個例項,t4得到初始化,呼叫Table含

有引數的構造方法,程式進行下去。

這樣就完成了對這個程式的真個的流程的分析,如果有錯誤的地方,或者還要補充的地方,還希望大家

指點一下,謝謝!!!

最後再總結一下:

初始化順序是:

(1) 先是父類的static變數和static初始化塊

(2)然後是子類的static變數和static初始化塊  

(3)父類的例項變數、初始化快

(4)父類的構造方法

(5)子類的例項變數、初始化快

(6)子類構造方法