構(gòu)造函數(shù)、構(gòu)造代碼塊和靜態(tài)代碼塊容易混淆,它們的執(zhí)行條件和執(zhí)行順序也常常容易犯迷。這里就針對(duì)這些問(wèn)題說(shuō)一下我個(gè)人的一些理解,順便對(duì)這部分內(nèi)容做個(gè)小結(jié)。
構(gòu)造函數(shù)
格式:類名(參數(shù)1,參數(shù)2,…){構(gòu)造函數(shù)執(zhí)行語(yǔ)句};
關(guān)于構(gòu)造函數(shù),以下幾點(diǎn)要注意:
1.對(duì)象一建立,就會(huì)調(diào)用與之相應(yīng)的構(gòu)造函數(shù),也就是說(shuō),不建立對(duì)象,構(gòu)造函數(shù)時(shí)不會(huì)運(yùn)行的。
2.構(gòu)造函數(shù)的作用是用于給對(duì)象進(jìn)行初始化。
3.構(gòu)造函數(shù)籠統(tǒng)來(lái)說(shuō)也是函數(shù),它具備函數(shù)的一些特性,也不具備一些特性,可以把它看成是特殊的函數(shù)。它可以重載(重載時(shí)參數(shù)類型與參數(shù)個(gè)數(shù)有一項(xiàng)不同即可,但僅僅函數(shù)返回值類型不同是不行的),可以被權(quán)限修飾符修飾,但是它沒(méi)有返回值(注意:這與平常所說(shuō)的函數(shù)返回值類型是void不同)。
4.當(dāng)一個(gè)類中沒(méi)有定義構(gòu)造函數(shù)時(shí),那么系統(tǒng)會(huì)默認(rèn)給該類加入一個(gè)空參數(shù)的構(gòu)造方法。但是當(dāng)在類中自定義構(gòu)造函數(shù)后,默認(rèn)的構(gòu)造函數(shù)就沒(méi)有了,即使是自定義的構(gòu)造函數(shù)也是空參數(shù)的也是這樣,因?yàn)槟钱吘故悄恪白远x”的!
5.構(gòu)造函數(shù)和一般函數(shù)不僅在寫(xiě)法上有不同,在運(yùn)行上也有不同。構(gòu)造函數(shù)是在對(duì)象一建立就運(yùn)行,給對(duì)象初始化,而一般函數(shù)是對(duì)象調(diào)用時(shí)才執(zhí)行,給對(duì)象添加對(duì)象具備的功能。
一個(gè)對(duì)象建立,構(gòu)造函數(shù)只運(yùn)行一次,而一般方法可以被該對(duì)象調(diào)用多次。
6.定義構(gòu)造函數(shù)的需求性:當(dāng)分析事物時(shí),該事物存在具備一些特性或者行為,那么將這些內(nèi)容定義在構(gòu)造函數(shù)中。
構(gòu)造代碼塊
格式:{構(gòu)造代碼塊執(zhí)行語(yǔ)句};
關(guān)于構(gòu)造代碼塊,以下幾點(diǎn)要注意:
1.構(gòu)造代碼塊的作用是給對(duì)象進(jìn)行初始化。
2.對(duì)象一建立就運(yùn)行構(gòu)造代碼塊了,而且優(yōu)先于構(gòu)造函數(shù)執(zhí)行。這里要強(qiáng)調(diào)一下,有對(duì)象建立,才會(huì)運(yùn)行構(gòu)造代碼塊,類不能調(diào)用構(gòu)造代碼塊的,而且構(gòu)造代碼塊與構(gòu)造函數(shù)的執(zhí)行順序是前者先于后者執(zhí)行。
3.構(gòu)造代碼塊與構(gòu)造函數(shù)的區(qū)別是:構(gòu)造代碼塊是給所有對(duì)象進(jìn)行統(tǒng)一初始化,而構(gòu)造函數(shù)是給對(duì)應(yīng)的對(duì)象初始化,因?yàn)闃?gòu)造函數(shù)是可以多個(gè)的,運(yùn)行哪個(gè)構(gòu)造函數(shù)就會(huì)建立什么樣的對(duì)象,但無(wú)論建立哪個(gè)對(duì)象,都會(huì)先執(zhí)行相同的構(gòu)造代碼塊。也就是說(shuō),構(gòu)造代碼塊中定義的是不同對(duì)象共性的初始化內(nèi)容。
靜態(tài)代碼塊
格式:static{靜態(tài)代碼塊執(zhí)行語(yǔ)句};
關(guān)于靜態(tài)代碼塊,要注意的是:
1.它是隨著類的加載而執(zhí)行,只執(zhí)行一次,并優(yōu)先于主函數(shù)。具體說(shuō),靜態(tài)代碼塊是由類調(diào)用的,當(dāng)然,建立對(duì)象的時(shí)候,它也會(huì)執(zhí)行,但是建立多個(gè)對(duì)象,它也是只會(huì)執(zhí)行一次,并不是說(shuō)每次建立對(duì)象它都要執(zhí)行,因?yàn)樗怯深愓{(diào)用的,且只執(zhí)行一次!就它優(yōu)先于主函數(shù)而執(zhí)行這點(diǎn)來(lái)說(shuō),因?yàn)橹骱瘮?shù)也是由類調(diào)用的,所以類可以控制著執(zhí)行的順序,而實(shí)際上,類調(diào)用時(shí),先執(zhí)行靜態(tài)代碼塊,然后才執(zhí)行主函數(shù)的。
2.靜態(tài)代碼塊其實(shí)就是給類初始化的,而構(gòu)造代碼塊是給對(duì)象初始化的。區(qū)分著理解比較容易記牢。
下面結(jié)合一個(gè)小例子來(lái)具體分析三者的用法。
classStaticCode{
intnum=9;
StaticCode(){
System.out.println("b");
}
static{
System.out.println("a");
}
{
System.out.println("c");
}
StaticCode(intx){
System.out.println("d");
}
}
publicclassStaticCodeDemo {
publicstaticvoidmain(String[] args){
newStaticCode(1);
}
}
運(yùn)行結(jié)果是
a
c
d
這是因?yàn)?,主函?shù)中的執(zhí)行語(yǔ)句是new StaticCode(1);因?yàn)檫@個(gè)語(yǔ)句調(diào)用了StaticCode類并調(diào)用StaticCode的一個(gè)構(gòu)造函數(shù)建立對(duì)象,那么在StaticCode類中,先執(zhí)行的是靜態(tài)代碼塊
static{
System.out.println("a");
}
它是在調(diào)用類時(shí)立即執(zhí)行,但此時(shí)還沒(méi)有建立對(duì)象。然后執(zhí)行的是構(gòu)造代碼塊,
{
System.out.println("c");
}
這是在建立對(duì)象時(shí)執(zhí)行,但它的執(zhí)行是優(yōu)先于構(gòu)造函數(shù)的。接著執(zhí)行的是對(duì)應(yīng)的構(gòu)造函數(shù)
StaticCode(intx){
System.out.println("d");
}
,這個(gè)構(gòu)造函數(shù)與new StaticCode(1);有著相同的參數(shù)個(gè)數(shù)和對(duì)應(yīng)的參數(shù)類型,執(zhí)行語(yǔ)句自動(dòng)匹配尋找對(duì)應(yīng)的構(gòu)造函數(shù)。
另外,StaticCode類中有個(gè)成員變量num,如果將靜態(tài)代碼塊改為
static{
System.out.println("a"+this.num);
}
則編譯不通過(guò),因?yàn)殪o態(tài)代碼塊只能調(diào)用靜態(tài)變量,非靜態(tài)成員變量在對(duì)象沒(méi)有建立前是不存在的,這也幫助理解了靜態(tài)代碼塊是在對(duì)象建立前執(zhí)行的。
如果將構(gòu)造代碼塊改為
{
System.out.println("c,num="+this.num);
}
那么將編譯無(wú)誤,運(yùn)行正確,因?yàn)闃?gòu)造代碼塊是在對(duì)象建立后才運(yùn)行的,是由對(duì)象調(diào)用的,對(duì)象建立后,成員變量num已經(jīng)存在了,所以不會(huì)出錯(cuò)。
運(yùn)行結(jié)果如下
a
c,num=9
d
匿名內(nèi)部類是沒(méi)有構(gòu)造器,那怎么來(lái)初始化匿名內(nèi)部類呢?使用構(gòu)造代碼塊!利用構(gòu)造代碼塊能夠達(dá)到為匿名內(nèi)部類創(chuàng)建一個(gè)構(gòu)造器的效果。
new InnerClass (String arg) {
? ? int a;
? ? int b;
? ? {? ?
? ? ? ? a = 10;
????????b = 11;
????}
}
1、使用匿名內(nèi)部類時(shí),我們必須是繼承一個(gè)類或者實(shí)現(xiàn)一個(gè)接口,但是兩者不可兼得,同時(shí)也只能繼承一個(gè)類或者實(shí)現(xiàn)一個(gè)接口。
2、匿名內(nèi)部類中是不能定義構(gòu)造函數(shù)的。
3、匿名內(nèi)部類中不能存在任何的靜態(tài)成員變量和靜態(tài)方法。
4、匿名內(nèi)部類為局部?jī)?nèi)部類,所以局部?jī)?nèi)部類的所有限制同樣對(duì)匿名內(nèi)部類生效。
5、匿名內(nèi)部類不能是抽象的,它必須要實(shí)現(xiàn)繼承的類或者實(shí)現(xiàn)的接口的所有抽象方法
下面是一些內(nèi)部類的知識(shí)點(diǎn)總結(jié)博客