構(gòu)造函數(shù)、構(gòu)造代碼塊和靜態(tài)代碼塊容易混淆毅弧,它們的執(zhí)行條件和執(zhí)行順序也常常容易犯迷气嫁。這里就針對這些問題說一下我個人的一些理解,順便對這部分內(nèi)容做個小結(jié)够坐。
構(gòu)造函數(shù)
格式:類名(參數(shù)1寸宵,參數(shù)2,…){構(gòu)造函數(shù)執(zhí)行語句}元咙;
關(guān)于構(gòu)造函數(shù)梯影,以下幾點(diǎn)要注意:
1.對象一建立,就會調(diào)用與之相應(yīng)的構(gòu)造函數(shù)庶香,也就是說甲棍,不建立對象,構(gòu)造函數(shù)時不會運(yùn)行的赶掖。
2.構(gòu)造函數(shù)的作用是用于給對象進(jìn)行初始化感猛。
3.構(gòu)造函數(shù)籠統(tǒng)來說也是函數(shù)七扰,它具備函數(shù)的一些特性,也不具備一些特性陪白,可以把它看成是特殊的函數(shù)颈走。它可以重載(重載時參數(shù)類型與參數(shù)個數(shù)有一項(xiàng)不同即可,但僅僅函數(shù)返回值類型不同是不行的)咱士,可以被權(quán)限修飾符修飾疫鹊,但是它沒有返回值(注意:這與平常所說的函數(shù)返回值類型是void不同)。
4.當(dāng)一個類中沒有定義構(gòu)造函數(shù)時司致,那么系統(tǒng)會默認(rèn)給該類加入一個空參數(shù)的構(gòu)造方法拆吆。但是當(dāng)在類中自定義構(gòu)造函數(shù)后,默認(rèn)的構(gòu)造函數(shù)就沒有了脂矫,即使是自定義的構(gòu)造函數(shù)也是空參數(shù)的也是這樣枣耀,因?yàn)槟钱吘故悄恪白远x”的!
5.構(gòu)造函數(shù)和一般函數(shù)不僅在寫法上有不同庭再,在運(yùn)行上也有不同捞奕。構(gòu)造函數(shù)是在對象一建立就運(yùn)行,給對象初始化拄轻,而一般函數(shù)是對象調(diào)用時才執(zhí)行颅围,給對象添加對象具備的功能。
一個對象建立恨搓,構(gòu)造函數(shù)只運(yùn)行一次院促,而一般方法可以被該對象調(diào)用多次。
6.定義構(gòu)造函數(shù)的需求性:當(dāng)分析事物時斧抱,該事物存在具備一些特性或者行為常拓,那么將這些內(nèi)容定義在構(gòu)造函數(shù)中。
構(gòu)造代碼塊
格式:{構(gòu)造代碼塊執(zhí)行語句}辉浦;
關(guān)于構(gòu)造代碼塊弄抬,以下幾點(diǎn)要注意:
1.構(gòu)造代碼塊的作用是給對象進(jìn)行初始化。
2.對象一建立就運(yùn)行構(gòu)造代碼塊了宪郊,而且優(yōu)先于構(gòu)造函數(shù)執(zhí)行掂恕。這里要強(qiáng)調(diào)一下,有對象建立弛槐,才會運(yùn)行構(gòu)造代碼塊懊亡,類不能調(diào)用構(gòu)造代碼塊的,而且構(gòu)造代碼塊與構(gòu)造函數(shù)的執(zhí)行順序是前者先于后者執(zhí)行丐黄。
3.構(gòu)造代碼塊與構(gòu)造函數(shù)的區(qū)別是:構(gòu)造代碼塊是給所有對象進(jìn)行統(tǒng)一初始化斋配,而構(gòu)造函數(shù)是給對應(yīng)的對象初始化孔飒,因?yàn)闃?gòu)造函數(shù)是可以多個的灌闺,運(yùn)行哪個構(gòu)造函數(shù)就會建立什么樣的對象艰争,但無論建立哪個對象,都會先執(zhí)行相同的構(gòu)造代碼塊桂对。也就是說甩卓,構(gòu)造代碼塊中定義的是不同對象共性的初始化內(nèi)容。
靜態(tài)代碼塊
格式:static{靜態(tài)代碼塊執(zhí)行語句}蕉斜;
關(guān)于靜態(tài)代碼塊逾柿,要注意的是:
1.它是隨著類的加載而執(zhí)行,只執(zhí)行一次宅此,并優(yōu)先于主函數(shù)机错。具體說,靜態(tài)代碼塊是由類調(diào)用的父腕,當(dāng)然弱匪,建立對象的時候,它也會執(zhí)行璧亮,但是建立多個對象萧诫,它也是只會執(zhí)行一次,并不是說每次建立對象它都要執(zhí)行枝嘶,因?yàn)樗怯深愓{(diào)用的帘饶,且只執(zhí)行一次!就它優(yōu)先于主函數(shù)而執(zhí)行這點(diǎn)來說群扶,因?yàn)橹骱瘮?shù)也是由類調(diào)用的及刻,所以類可以控制著執(zhí)行的順序,而實(shí)際上竞阐,類調(diào)用時提茁,先執(zhí)行靜態(tài)代碼塊,然后才執(zhí)行主函數(shù)的馁菜。
2.靜態(tài)代碼塊其實(shí)就是給類初始化的茴扁,而構(gòu)造代碼塊是給對象初始化的。區(qū)分著理解比較容易記牢汪疮。
下面結(jié)合一個小例子來具體分析三者的用法峭火。
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í)行語句是new StaticCode(1);因?yàn)檫@個語句調(diào)用了StaticCode類并調(diào)用StaticCode的一個構(gòu)造函數(shù)建立對象智嚷,那么在StaticCode類中卖丸,先執(zhí)行的是靜態(tài)代碼塊
static{
System.out.println("a");
}
它是在調(diào)用類時立即執(zhí)行,但此時還沒有建立對象盏道。然后執(zhí)行的是構(gòu)造代碼塊稍浆,
{
System.out.println("c");
}
這是在建立對象時執(zhí)行,但它的執(zhí)行是優(yōu)先于構(gòu)造函數(shù)的。接著執(zhí)行的是對應(yīng)的構(gòu)造函數(shù)
StaticCode(intx){
System.out.println("d");
}
衅枫,這個構(gòu)造函數(shù)與new StaticCode(1);有著相同的參數(shù)個數(shù)和對應(yīng)的參數(shù)類型嫁艇,執(zhí)行語句自動匹配尋找對應(yīng)的構(gòu)造函數(shù)。
另外弦撩,StaticCode類中有個成員變量num步咪,如果將靜態(tài)代碼塊改為
static{
System.out.println("a"+this.num);
}
則編譯不通過,因?yàn)殪o態(tài)代碼塊只能調(diào)用靜態(tài)變量益楼,非靜態(tài)成員變量在對象沒有建立前是不存在的猾漫,這也幫助理解了靜態(tài)代碼塊是在對象建立前執(zhí)行的。
如果將構(gòu)造代碼塊改為
{
System.out.println("c,num="+this.num);
}
那么將編譯無誤感凤,運(yùn)行正確悯周,因?yàn)闃?gòu)造代碼塊是在對象建立后才運(yùn)行的,是由對象調(diào)用的陪竿,對象建立后队橙,成員變量num已經(jīng)存在了,所以不會出錯萨惑。
運(yùn)行結(jié)果如下
a
c,num=9
d
匿名內(nèi)部類是沒有構(gòu)造器捐康,那怎么來初始化匿名內(nèi)部類呢?使用構(gòu)造代碼塊庸蔼!利用構(gòu)造代碼塊能夠達(dá)到為匿名內(nèi)部類創(chuàng)建一個構(gòu)造器的效果解总。
new InnerClass (String arg) {
? ? int a;
? ? int b;
? ? {? ?
? ? ? ? a = 10;
????????b = 11;
????}
}
1、使用匿名內(nèi)部類時姐仅,我們必須是繼承一個類或者實(shí)現(xiàn)一個接口花枫,但是兩者不可兼得,同時也只能繼承一個類或者實(shí)現(xiàn)一個接口掏膏。
2劳翰、匿名內(nèi)部類中是不能定義構(gòu)造函數(shù)的。
3馒疹、匿名內(nèi)部類中不能存在任何的靜態(tài)成員變量和靜態(tài)方法佳簸。
4、匿名內(nèi)部類為局部內(nèi)部類颖变,所以局部內(nèi)部類的所有限制同樣對匿名內(nèi)部類生效生均。
5、匿名內(nèi)部類不能是抽象的腥刹,它必須要實(shí)現(xiàn)繼承的類或者實(shí)現(xiàn)的接口的所有抽象方法
下面是一些內(nèi)部類的知識點(diǎn)總結(jié)博客