在Java類中靈活使用Static關(guān)鍵字
用專業(yè)術(shù)語(yǔ)來(lái)說(shuō),只有利用了new關(guān)鍵字創(chuàng)建對(duì)象后,才會(huì)在系統(tǒng)中為其創(chuàng)建存儲(chǔ)空間。不過(guò)在有些特殊的情況下,程序員可能希望在沒(méi)有創(chuàng)建對(duì)象的時(shí)候就能夠?yàn)槟硞€(gè)特定的成員分配存儲(chǔ)空間或者可以調(diào)用某個(gè)方法等等。在Java中能否實(shí)現(xiàn)這個(gè)需求呢?
一、不建立對(duì)象即想使用的兩種實(shí)際情況。
筆者提到的這個(gè)問(wèn)題是否是無(wú)中生有呢?其實(shí)不然。在實(shí)際應(yīng)用程序開(kāi)發(fā)中,就經(jīng)常會(huì)遇到這種情況。如現(xiàn)在需要三個(gè)對(duì)象,分別用來(lái)計(jì)算圓的面積、圓球的體積、圓柱的體積。在這三個(gè)對(duì)象的方法中,都需要用到一個(gè)叫做圓周率的常量,而且這個(gè)圓周率是固定不變的。所以,在程序開(kāi)發(fā)中,對(duì)于這些公用的成員變量最好能夠統(tǒng)一管理。當(dāng)調(diào)整成員變量的精度時(shí),其運(yùn)算結(jié)果的精度也會(huì)隨之調(diào)整。從程序員的角度來(lái)看,這就是要求在沒(méi)有創(chuàng)建對(duì)象之前就要給成員變量分配存儲(chǔ)空間,以方便其他的類可以因用這個(gè)變量。而這個(gè)需求如果沒(méi)有Statci關(guān)鍵字的話就無(wú)法實(shí)現(xiàn)。
第二種情況就是程序員可能希望某個(gè)方法不予包含它的類的任何對(duì)象關(guān)聯(lián)在一起。這個(gè)讀起來(lái)可能有點(diǎn)拗口。簡(jiǎn)單的說(shuō),就是即使沒(méi)有使用new關(guān)鍵字創(chuàng)建對(duì)象的情況下,程序員仍然能夠調(diào)用這個(gè)方法。也就是說(shuō),在創(chuàng)建類的時(shí)候就需要為這個(gè)方法分配存儲(chǔ)空間。就好像造汽車時(shí),在做汽車設(shè)計(jì)圖紙時(shí)就需要把發(fā)動(dòng)機(jī)準(zhǔn)備好。那么即使汽車還沒(méi)造好,這個(gè)發(fā)動(dòng)起也可以先拿來(lái)看看。此時(shí)也需要采用Static關(guān)鍵字來(lái)完成這個(gè)需求。
二、Static關(guān)鍵字的用途。
簡(jiǎn)單的說(shuō),Static關(guān)鍵字的用途就是在創(chuàng)建類的時(shí)候就給特定的成員或者方法分配存儲(chǔ)空間。當(dāng)程序員在成員變量或者方法前面加上Static關(guān)鍵字時(shí),就表示這些成員與方法不會(huì)與包含它的那個(gè)類的任何對(duì)象實(shí)例關(guān)聯(lián)在一起。換一句話就是說(shuō),即使沒(méi)有創(chuàng)建這個(gè)類的對(duì)象,程序員仍然可以調(diào)用這個(gè)類中的成員或者方法。因?yàn)樗麄儗?shí)際上已經(jīng)存在,系統(tǒng)已經(jīng)為他們分配了存儲(chǔ)空間。不過(guò)需要注意的是,Static關(guān)鍵字定義的成員與方法,畢竟與傳統(tǒng)的對(duì)象創(chuàng)建方法有所差異。所以無(wú)論是在定義時(shí)還是在具體的引用過(guò)程中,都有所差異。程序開(kāi)發(fā)人員必須了解這種差異,并在實(shí)際的工作中要引起重視。特別是如果有其他語(yǔ)言開(kāi)發(fā)經(jīng)驗(yàn)的程序員,不要將Java語(yǔ)言的這個(gè)特性與其他語(yǔ)言搞混,否則的話很容易出現(xiàn)錯(cuò)誤。
三、利用Static關(guān)鍵字來(lái)定義成員變量。
如上面那個(gè)案例中,需要定義一個(gè)類,然后在這個(gè)類中需要用到一個(gè)叫做圓周率的成員。如果我們將這個(gè)成員命名為pi,則這個(gè)類可以按照下面的方法定義成員變量。
- Class circle{
- Static float pi=3.14
- }
這個(gè)類的定義跟其他類最大的不同,就是在成員變量前面加了一個(gè)static關(guān)鍵字。此時(shí)就將這個(gè)成員變量設(shè)置為了staitc狀態(tài)。其實(shí)在創(chuàng)建這個(gè)類的時(shí)候,系統(tǒng)就為其分配了一份存儲(chǔ)空間。而不是在創(chuàng)建對(duì)象的時(shí)候再創(chuàng)建的。也就是說(shuō),現(xiàn)在就將這個(gè)成員變量跟包含它的類獨(dú)立出來(lái)。在這種情況下,如果利用new關(guān)鍵字來(lái)創(chuàng)建對(duì)象,那么這個(gè)成員變量都是指向同一個(gè)。即程序員如果利用這個(gè)類創(chuàng)建三個(gè)對(duì)象時(shí),其成員變量pi都指向同一個(gè)存儲(chǔ)空間。為此不同對(duì)象內(nèi)的成員變量pi的值都是相同的,因?yàn)槠鋵?shí)際上都指的是同一東西。所以說(shuō),要統(tǒng)一多個(gè)對(duì)象中成員變量的值是非常簡(jiǎn)單的。只需要在定義類的時(shí)候,在這個(gè)成員變量的前面加上關(guān)鍵字static即可。
那么該如何引用這個(gè)成員變量呢?據(jù)筆者所知,現(xiàn)在主要有兩種引用的方法。不過(guò)筆者只用其中的一種。第一種方式就是跟傳統(tǒng)的引用方式相同。也就是說(shuō),第一步是創(chuàng)建類(根據(jù)需要可以在某個(gè)成員變量前面利用static關(guān)鍵字加以修飾),第二步是創(chuàng)建對(duì)象,第三步就是通過(guò)對(duì)象來(lái)引用成員變量。引用的格式就是對(duì)象名.成員變量。這種方法就是比較傳統(tǒng)的方法,通過(guò)對(duì)象去定位成員變量。很明顯,如果采用這種方法的話,在代碼中就不能夠體現(xiàn)這個(gè)成員變量到底是static變量呢,還是非static變量。所以說(shuō)這會(huì)給程序員閱讀代碼帶來(lái)麻煩。
第二種方法是直接通過(guò)類來(lái)調(diào)用。也就說(shuō)可以通過(guò)類名.成員變量的形式來(lái)加以調(diào)用。各位讀者知道為什么可以以這種形式加以調(diào)用呢?這主要是因?yàn)?,根?jù)這個(gè)類創(chuàng)建的對(duì)象,只要成員變量采用了關(guān)鍵字static修飾,他們他們指向的都是同一個(gè)變量。即系統(tǒng)只為他們分配了一份存儲(chǔ)空間。所以只通過(guò)類名就可以唯一的關(guān)聯(lián)到這個(gè)靜態(tài)的成員變量。而如果沒(méi)有利用static關(guān)鍵字修飾的成員變量就不行。因?yàn)榇藭r(shí)根據(jù)這個(gè)類創(chuàng)建的多個(gè)對(duì)象,其內(nèi)部的成員變量是各自獨(dú)立的,也就是說(shuō)每個(gè)對(duì)象內(nèi)部的成員變量都有一個(gè)對(duì)應(yīng)的存儲(chǔ)位置。所以說(shuō),如果一個(gè)類有多個(gè)對(duì)象,那么就不能夠通過(guò)對(duì)象直接關(guān)聯(lián)到變量對(duì)應(yīng)的存儲(chǔ)位置了。系統(tǒng)不知道這個(gè)類對(duì)應(yīng)的對(duì)象到底是哪個(gè),即存在一對(duì)多的情況。而采用了static關(guān)鍵字修飾的變量,無(wú)論有多少個(gè)對(duì)象,其都是一對(duì)一的關(guān)系。所以,可以通過(guò)類名.成員變量名的方式來(lái)直接引用這個(gè)成員變量。
雖然兩種方法都可以實(shí)現(xiàn)對(duì)static變量的引用。但是筆者建議大家采用第二種方式。并不是說(shuō)采用第二種方式更加的便捷或者說(shuō)可以提高應(yīng)用程序的性能。筆者這么建議,主要是從代碼的閱讀性上來(lái)考慮的。如果采用對(duì)象名.成員變量這種形式來(lái)引用的話,那么就不怎么直觀的反應(yīng)這個(gè)變量的特殊性。而如果采用類名.成員變量的形式來(lái)引用的話,那么成語(yǔ)員就可以一目了然的知道這個(gè)成員變量就是靜態(tài)變量。這有利于代碼的閱讀與修改。
四、利用Static關(guān)鍵字來(lái)定義成員方法。
利用Static關(guān)鍵字來(lái)定義靜態(tài)的成員方法,其實(shí)跟靜態(tài)成員變量的定義類似。只需要在某個(gè)方法前面加上關(guān)鍵字static即可。不過(guò)在內(nèi)部的實(shí)現(xiàn)機(jī)制上,兩個(gè)還是有差別的。從以上的分析中可以看出,當(dāng)將某個(gè)成員變量定義為靜態(tài)變量時(shí),其實(shí)內(nèi)部數(shù)據(jù)創(chuàng)建的方式得到了改變。因?yàn)檎G闆r下,非靜態(tài)成員變量每個(gè)對(duì)象都有一個(gè)存儲(chǔ)空間,也就是說(shuō)一個(gè)類如果有多少個(gè)對(duì)象則這個(gè)成員變量就有多少個(gè)存儲(chǔ)空間。而如果成員變量設(shè)置為靜態(tài)變量時(shí),則一個(gè)類中的一個(gè)靜態(tài)成員變量只有一個(gè)存儲(chǔ)空間。即使這個(gè)類創(chuàng)建了數(shù)百個(gè)對(duì)象,但是這個(gè)對(duì)象中的靜態(tài)成員變量也只有一個(gè)存儲(chǔ)空間。這就是靜態(tài)成員變量與非靜態(tài)成員變量的主要差異。但是如果將某個(gè)方法定義為靜態(tài)方法的話,差別就沒(méi)有這么大。這主要是因?yàn)榉椒ㄖ簧婕暗秸{(diào)用,很少涉及到存儲(chǔ)空間的分配。
而至于這個(gè)靜態(tài)方法的調(diào)用,跟靜態(tài)變量的調(diào)用相同。即可以利用對(duì)象名來(lái)調(diào)用,也可以利用類名來(lái)調(diào)用。同理,筆者建議是采用類名來(lái)調(diào)用,這可以強(qiáng)調(diào)靜態(tài)方法的靜態(tài)性。另外需要注意的是,創(chuàng)建靜態(tài)方法的一個(gè)重要的用途就是在不創(chuàng)建任何對(duì)象的情況下,就來(lái)調(diào)用靜態(tài)的方法。此時(shí)就只能夠通過(guò)類名來(lái)調(diào)用這個(gè)靜態(tài)方法。因?yàn)閷?duì)象根本沒(méi)有被創(chuàng)建。
所以如果static關(guān)鍵字用于修飾成員變量,即把這個(gè)變量設(shè)置為靜態(tài)變量,這主要是用來(lái)解決多個(gè)對(duì)象共享同一個(gè)變量的需求。而將某個(gè)方法設(shè)置為靜態(tài)方法,這主要是用來(lái)在不創(chuàng)建任何對(duì)象的情況下就可以使用某個(gè)方法。故靜態(tài)變量與靜態(tài)方法雖然實(shí)現(xiàn)與引用的方式相同,但是兩者解決問(wèn)題的側(cè)重點(diǎn)是不同的。
【編輯推薦】