1.普通變量的初始化 看如下程序 [html] class Window{ public Window(int maker) { System.out.println('Window('+maker+')'); } } class House{ Window w1 = new Window(1); public House() { System.out.println('House()'); w3 = new Window(33); } Window w2 = new Window(2); void f(){ System.out.println('f()'); } Window w3 = new Window(3); } public class Test { public static void main(String[] args) { House h = new House(); h.f(); } } /* 結(jié)果如下: Window(1) Window(2) Window(3) House() Window(33) f() */ 分析:普通變量在類中的任何方法(包括構(gòu)造函數(shù))之前初始化(規(guī)則一)。 2.靜態(tài)變量的初始化 [html] class Bowl{ public Bowl(int maker) { System.out.println('Bowl('+maker+')'); } void f1(int maker){ System.out.println('f1('+maker+')'); } } class Table{ static Bowl bowl1 = new Bowl(1); static Bowl bowl2 = new Bowl(2); public Table() { System.out.println('Table()'); bowl2.f1(1); } void f2(int maker){ System.out.println('f2('+maker+')'); } } class Cupboard{ Bowl bowl3 = new Bowl(3); static Bowl bowl4 = new Bowl(4); static Bowl bowl5 = new Bowl(5); public Cupboard() { System.out.println('cupboard()'); bowl4.f1(2); } void f3(int maker){ System.out.println('f3('+maker+')'); } } public class Test { static Table table = new Table(); static Cupboard cupboard = new Cupboard(); public static void main(String[] args) { System.out.println('creating new cupboard() in main'); new Cupboard(); System.out.println('creating new cupboard() in main'); new Cupboard(); table.f2(1); cupboard.f3(1); } } /* 結(jié)果如下: Bowl(1) Bowl(2) Table() f1(1) Bowl(4) Bowl(5) Bowl(3) cupboard() f1(2) creating new cupboard() in main Bowl(3) cupboard() f1(2) creating new cupboard() in main Bowl(3) cupboard() f1(2) f2(1) f3(1) */ 分析: 1.首先程序總共有4個(gè)類(Bowl,Table,Cupboard,Test),Bowl沒有靜態(tài)變量和靜態(tài)方法;Table中有靜態(tài)變量bowl1、bowl2;Cupboard中有普通變量bowl3,靜態(tài)變量bowl4、bowl5;Test中有靜態(tài)變量table、cupboard。 2.根據(jù)規(guī)則:使用static命名的變量或者使用static{}包括起來的區(qū)域,都在類被加載時(shí)進(jìn)行初始化(規(guī)則二)。 3.虛擬機(jī)首先加載Test,需要初始化table變量,加載Table類。Table類中有靜態(tài)變量bowl1,bowl2,初始化它們,輸出'Bowl(1),Bowl(2)',再調(diào)用構(gòu)造函數(shù)來new對象,輸出'Table(),f1(1)'。然后加載Cupboard類,初始化靜態(tài)變量bowl4,bowl5,輸出'Bowl(4),Bowl(5)',調(diào)用構(gòu)造函數(shù)來new對象,首先初始化普通變量bowl3,輸出'Bowl(3)',然后構(gòu)造函數(shù),輸出'cupboard(),f1(2)'。 4.執(zhí)行main方法,先輸出'creating new cupboard() in main',執(zhí)行new Cupboard(),這時(shí)靜態(tài)變量都初始化了,不必繼續(xù)初始化。初始化一般變量bowl3,輸出'bowl3',然后調(diào)用構(gòu)造函數(shù),輸出'cupboard(),f1(2)'。在輸出'creating new cupboard() in main',同理輸出'bowl3,cupboard(),f1(2)',最后繼續(xù)執(zhí)行main函數(shù),輸出'f2(1),f3(1)'。 3.靜態(tài)代碼塊的初始化 [html] class Spoon{ public Spoon(int maker) { System.out.println('Spoon('+maker+')'); } static int i; static Spoon s = new Spoon(1); static{ System.out.println('static code '); i = 47; } } public class Test { public static void main(String[] args) { new Spoon(2); } } /* Spoon(1) static code Spoon(2) */ /* 如果寫成 static{ System.out.println('static code '); i = 47; } static Spoon s = new Spoon(1); 結(jié)果為: static code Spoon(1) Spoon(2) */ 分析:靜態(tài)代碼塊跟靜態(tài)變量都是類加載時(shí)進(jìn)行初始化的(同等條件下,初始化順序由書寫順序決定) 4.非靜態(tài)代碼塊 [html] class Spoon{ public Spoon(int maker) { System.out.println('Spoon('+maker+')'); } static int i; static Spoon s = new Spoon(1); static{ System.out.println('static code '); i = 47; } int a; //非靜態(tài)代碼塊與直接為變量賦值效果相同,只不過可以寫更為復(fù)雜的代碼,非靜態(tài)代碼塊一般用于內(nèi)部類中 { System.out.println('non-static instatnce'); a = 1; } } public class Test { public static void main(String[] args) { new Spoon(2); new Spoon(3); } } /* non-static instatnce Spoon(1) static code non-static instatnce Spoon(2) non-static instatnce Spoon(3) */ 分析: 1.main函數(shù)執(zhí)行new Spoon(2)語句,首先加載Spoon類,先初始化靜態(tài)變量s,s調(diào)用new Spoon(1),此時(shí)類Spoon已經(jīng)加載,所以不用管靜態(tài)變量和靜態(tài)代碼塊了,然后調(diào)用非靜態(tài)代碼塊和構(gòu)造函數(shù),輸出'non-static code,spoon(1)'。 2.初始化靜態(tài)代碼塊,輸出'static code'。 3.執(zhí)行new spoon(2)語句輸出“non-static instatnce,Spoon(2)“。 4.執(zhí)行'new spoon(3)'語句輸出”non-static instatnce,Spoon(3)”。 可以嘗試調(diào)換靜態(tài)變量s和靜態(tài)代碼塊的順序,發(fā)現(xiàn)只是1和2的先后順序改變而已。 在看下面這個(gè)程序 [cpp] class T{ public T() { System.out.println('T constructor'); } } class Spoon{ public Spoon(int maker) { System.out.println('Spoon('+maker+')'); } int a; //非靜態(tài)代碼塊與直接為變量賦值效果相同,只不過可以寫更為復(fù)雜的代碼,非靜態(tài)代碼塊一般用于內(nèi)部類中 { System.out.println('non-static instatnce'); a = 1; } T t1 = new T(); } public class Test { public static void main(String[] args) { new Spoon(2); } } /* non-static instatnce T constructor Spoon(2) */ 通過這個(gè)程序,可以發(fā)現(xiàn)非靜態(tài)變量和非靜態(tài)代碼塊順序由書寫順序決定。 5.總結(jié): 以Dog類為例 1.當(dāng)?shù)谝淮螆?zhí)行到需要使用Dog類時(shí)(如Dog d = new Dog),java首先通過尋找classpath來找到Dog.class,進(jìn)行加載. 2.初始化Dog類的靜態(tài)變量和靜態(tài)代碼塊(按書寫順序,若靜態(tài)變量或代碼塊中還有new Dog,此時(shí)不用再管靜態(tài)變 量和代碼塊了,如第五個(gè)程序中的'static Spoon s = new Spoon(1)')。 3.系統(tǒng)給類分配足夠大的內(nèi)存空間,初始化非靜態(tài)變量和非靜態(tài)代碼塊(順序由書寫順序決定) 4.最后執(zhí)行Dog類的構(gòu)造函數(shù)。 5.以后如果還要new Dog類對象時(shí)(不是第一次使用了),重復(fù)3和4的步驟,不會(huì)再去初始化靜態(tài)變量和靜態(tài)代碼 塊了。 大家可以自己寫程序?qū)嶒?yàn)一下。 6.子類繼承父類時(shí)的初始化順序 1.系統(tǒng)啟動(dòng)時(shí),首先初始化父類和子類的static變量和塊 2.初始化父類的普通變量,調(diào)用父類的構(gòu)造函數(shù) 3.初始化子類的普通變量,調(diào)用子類的構(gòu)造函數(shù) 7.附記 由于個(gè)人能力有限,第一次學(xué)習(xí)只了解這些了,有什么錯(cuò)誤,請多多指教。 http://www./Javabc/620714.htmlwww.truehttp://www./Javabc/620714.htmlTechArticle1.普通變量的初始化 看如下程序 [html] class Window{ public Window(int maker) { System.out.println(Window(+maker+)); } } class House{ Window w1 = new Window(1); public Ho...
|
|