abstract:初始化代碼塊在18篇-類的基本要素中說(shuō)到,類的三大成員:成員變量、構(gòu)造方法、方法,初始化代碼塊是類的第4個(gè)成員初始化塊用于對(duì)類或者對(duì)象的初始化,一個(gè)類的初始化塊可以有0~多個(gè),按先后順序執(zhí)行跟實(shí)例方法-->類方法、實(shí)例變量-->類變量一樣,也可以用static修飾初始化塊,靜態(tài)初始化塊-->非靜態(tài)初始化塊初始化塊總是先于構(gòu)造器執(zhí)行非靜態(tài)初始化塊非靜態(tài)初始化塊相當(dāng)于是對(duì)構(gòu)造器的補(bǔ)充
初始化代碼塊
在18篇-類的基本要素中說(shuō)到,類的三大成員:成員變量、構(gòu)造方法、方法,初始化代碼塊是類的第4個(gè)成員
初始化塊用于對(duì)類或者對(duì)象的初始化,
一個(gè)類的初始化塊可以有0~多個(gè),按先后順序執(zhí)行
跟實(shí)例方法-->類方法、實(shí)例變量-->類變量一樣,也可以用static修飾初始化塊,靜態(tài)初始化塊-->非靜態(tài)初始化塊
初始化塊總是先于構(gòu)造器執(zhí)行
非靜態(tài)初始化塊
非靜態(tài)初始化塊相當(dāng)于是對(duì)構(gòu)造器的補(bǔ)充,用于創(chuàng)建對(duì)象時(shí)給對(duì)象的初始化,在構(gòu)造器之間執(zhí)行
如果一段初始化代碼對(duì)所有對(duì)象完全相同,且無(wú)需接收參數(shù),那就可以將其提取到非靜態(tài)初始化代碼塊中
在繼承中,先后執(zhí)行父類A的非靜態(tài)塊、構(gòu)造器,再執(zhí)行父類B的非靜態(tài)塊、構(gòu)造器,最后才執(zhí)行子類的非靜態(tài)塊、構(gòu)造器
實(shí)際上,經(jīng)過(guò)編譯后,非靜態(tài)塊已經(jīng)添加到構(gòu)造器中,且位于所有構(gòu)造器代碼的前面
靜態(tài)初始化塊
靜態(tài)初始化塊用static修飾,又叫類初始化塊
非靜態(tài)塊負(fù)責(zé)對(duì)對(duì)象執(zhí)行初始化,而類初始化塊負(fù)責(zé)對(duì)類進(jìn)行初始化,因此類初始化塊是在類初始化階段就執(zhí)行
靜態(tài)塊跟靜態(tài)方法一樣,不能訪問(wèn)非靜態(tài)成員
在繼承中,先后執(zhí)行父類A的靜態(tài)塊,父類B的靜態(tài)塊,最后子類的靜態(tài)塊,然后再執(zhí)行父類A的非靜態(tài)塊和構(gòu)造器,然后是B類,最后執(zhí)行子類的非靜態(tài)塊和構(gòu)造器
因?yàn)殪o態(tài)塊是在類的初始化階段完成的,因此在創(chuàng)建某個(gè)類的第二個(gè)對(duì)象時(shí),該類的靜態(tài)塊就不會(huì)執(zhí)行了
下面通過(guò)一段代碼,看看繼承中的靜態(tài)塊、非靜態(tài)塊、構(gòu)造方法的執(zhí)行順序
public class Test{ public static void main(String[] args) { C c1=new C(); System.out.println("--------下面第二次創(chuàng)建C類對(duì)象---------"); C c2=new C(); } }class C extends B{ static { System.out.println("C的靜態(tài)代碼塊"); } { System.out.println("C的非靜態(tài)代碼塊"); } C(){ System.out.println("C的無(wú)參構(gòu)造方法"); } C(String str){ System.out.println("C的有參構(gòu)造方法"); } }class B extends A{ static { System.out.println("B的靜態(tài)代碼塊"); } { System.out.println("B的非靜態(tài)代碼塊"); } B(){ System.out.println("B的無(wú)參構(gòu)造方法"); } B(String str){ System.out.println("B的有參構(gòu)造方法"); } }class A{ static { System.out.println("A的靜態(tài)代碼塊"); } { System.out.println("A的非靜態(tài)代碼塊"); } A(){ System.out.println("A的無(wú)參構(gòu)造方法"); } A(String str){ System.out.println("A的有參構(gòu)造方法"); } }
輸出為:
A的靜態(tài)代碼塊
B的靜態(tài)代碼塊
C的靜態(tài)代碼塊
A的非靜態(tài)代碼塊
A的無(wú)參構(gòu)造方法
B的非靜態(tài)代碼塊
B的無(wú)參構(gòu)造方法
C的非靜態(tài)代碼塊
C的無(wú)參構(gòu)造方法
--------下面第二次創(chuàng)建C類對(duì)象---------
A的非靜態(tài)代碼塊
A的無(wú)參構(gòu)造方法
B的非靜態(tài)代碼塊
B的無(wú)參構(gòu)造方法
C的非靜態(tài)代碼塊
C的無(wú)參構(gòu)造方法
靜態(tài)初始化塊與靜態(tài)成員變量的執(zhí)行順序
JVM第一次使用某個(gè)類時(shí),在準(zhǔn)備階段給所有靜態(tài)成員分配內(nèi)存,在初始化階段初始化這些靜態(tài)成員變量,就是執(zhí)行初始化代碼或者聲明成員變量時(shí)指定的初始值,執(zhí)行順序與源代碼中的順序相同
按源代碼中的先后順序執(zhí)行,見(jiàn)示例代碼:
public class Test{ public static void main(String[] args) { A a=new A(); System.out.println(a.num); //輸出10 } }class A{ public static int num=6; static{ num=10; } }