Java類(lèi)初始化時(shí)初始化塊、靜態(tài)初始化塊和構(gòu)造器之間的關(guān)系
????從某種角度上來(lái)看,初始化塊是構(gòu)造器的補(bǔ)充,初始化塊總是在構(gòu)造器執(zhí)行之前執(zhí)行。與構(gòu)造器不同的是,初始化塊是一段固定執(zhí)行的代碼,不能接收任何參數(shù)。因此初始化塊對(duì)于同一個(gè)類(lèi)的所有對(duì)象所進(jìn)行的初始化處理完全相同?;谶@個(gè)原因,如果有一段初始化處理代碼對(duì)所有對(duì)象都通用,且無(wú)需接收任何參數(shù),則可以把它們從構(gòu)造器中提取出來(lái)放在初始化塊中。
????如果定義初始化塊時(shí)使用了static修飾符,則這個(gè)初始化塊就變成了靜態(tài)初始化塊,負(fù)責(zé)對(duì)類(lèi)進(jìn)行初始化。靜態(tài)初始化塊是類(lèi)相關(guān)的,系統(tǒng)將在類(lèi)初始化階段執(zhí)行靜態(tài)初始化塊,而不是在創(chuàng)建對(duì)象時(shí)才執(zhí)行。因此靜態(tài)初始化塊總是比普通初始化塊先執(zhí)行。
????系統(tǒng)會(huì)在類(lèi)初始化階段上溯到最頂層的父類(lèi)向下執(zhí)行靜態(tài)類(lèi)初始化塊,然后再上溯到頂層的父類(lèi)執(zhí)行初始化快,最后才是上溯到最頂層父類(lèi)向下執(zhí)行構(gòu)造器。當(dāng)類(lèi)已經(jīng)初始化完成后,這個(gè)類(lèi)在該虛擬機(jī)中將一直存在。第二次新建該類(lèi)的實(shí)例時(shí),將不再執(zhí)行靜態(tài)初始化塊,只執(zhí)行初始化塊和類(lèi)構(gòu)造器。
????看下面這個(gè)例子:
public class Main {
public static void main(String[] args){
new second();
new second();
}
}
class first{
static{
System.out.print("類(lèi)first的靜態(tài)初始化塊\n");
}
{
System.out.print("類(lèi)first的初始化塊\n");
}
public first(){
System.out.print("類(lèi)first的無(wú)參構(gòu)造\n");
}
}
class second extends first{
static{
System.out.print("類(lèi)second的靜態(tài)初始化塊\n");
}
{
System.out.print("類(lèi)second的初始化塊\n");
}
public second(){
System.out.print("類(lèi)second的無(wú)參構(gòu)造\n");
}
}
????最后的輸出結(jié)果是:
類(lèi)first的靜態(tài)初始化塊
類(lèi)second的靜態(tài)初始化塊
類(lèi)first的初始化塊
類(lèi)first的無(wú)參構(gòu)造
類(lèi)second的初始化塊
類(lèi)second的無(wú)參構(gòu)造
類(lèi)first的初始化塊
類(lèi)first的無(wú)參構(gòu)造
類(lèi)second的初始化塊
類(lèi)second的無(wú)參構(gòu)造
????實(shí)際上,初始化塊是一個(gè)假象,使用javac編譯Java類(lèi)之后,所有的初始化塊將消失,初始化塊中的代碼將會(huì)被“還原”到每個(gè)構(gòu)造器中,且位于所有代碼的前面。
????靜態(tài)初始化快和聲明靜態(tài)成員變量的執(zhí)行有先后順序。