java 静态方法与实例方法的区别_静态方法与实例方法的区分
Java系列之:看似簡(jiǎn)單的問題?靜態(tài)方法和實(shí)例化方法的區(qū)別
Java程序啟動(dòng)class文件被讀取時(shí)類被加載,如果有static方法,此時(shí)會(huì)分配內(nèi)存,非static方法實(shí)例化類時(shí)才在內(nèi)存中分配控件存儲(chǔ),引用存儲(chǔ)在堆棧中,實(shí)體存儲(chǔ)在堆中
最大的區(qū)別在于內(nèi)存。靜態(tài)方法在程序開始時(shí)生成內(nèi)存,實(shí)例方法在程序運(yùn)行中生成內(nèi)存,所以靜態(tài)方法可以直接調(diào)用,實(shí)例方法要先成生實(shí)例,通過實(shí)例調(diào)用方法,靜態(tài)速度很快,但是多了會(huì)占內(nèi)存。任何語言都是對(duì)內(nèi)存和磁盤的操作,至于是否面向?qū)ο?只是軟件層的問題,底層都是一樣的,只是實(shí)現(xiàn)方法不同。靜態(tài)內(nèi)存是連續(xù)的,因?yàn)槭窃诔绦蜷_始時(shí)就生成了,而實(shí)例申請(qǐng)的是離散的空間,所以當(dāng)然沒有靜態(tài)方法快,而且靜態(tài)內(nèi)存是有限制的,太多了程序會(huì)啟動(dòng)不了。
方法是我們每天都在寫得,很多程序員大多都使用實(shí)例化方法,而很少使用靜態(tài)方法,問原因也說不出來所以然,或者簡(jiǎn)單的回答兩者定義的區(qū)別,靜態(tài)方法不需要new就可以使用實(shí)例化方法需要new了以后才可以使用。。。。我們真的理解了嗎?
從實(shí)際項(xiàng)目開發(fā)說起,這里有開發(fā)項(xiàng)目的三種方式:
開發(fā)項(xiàng)目中把BLL和DAL分開,在BLL調(diào)用DAL的代碼。
一、在DAL中使用靜態(tài)方法,不創(chuàng)建實(shí)例直接調(diào)用(大概有很多人都使用這種方式開發(fā))
class DAL
{
public static string GetUserName(...);
}
在BLL中調(diào)用:DAL.GetUserName();
二、在DAL中使用實(shí)例方法,采用靜態(tài)成員模式(或Singleton)通過實(shí)例來調(diào)用:class DAL
{
public static readonly DAL dal = new DAL();
public string GetUserName(...);
}
在BLL中調(diào)用:DAL.dal.GetUserName();
三、在DAL中使用實(shí)例方法,每次調(diào)用之前先創(chuàng)建DAL對(duì)象的實(shí)例:class DAL
{
public string GetUserName(...);
}
在BLL中調(diào)用:DAL dal = new DAL();
dal.GetUserName();
---------------------------------------------------------------
開發(fā)方式一:我以為在一些情況下(比如調(diào)用多個(gè)數(shù)據(jù)庫(kù)、GetUserName(...)內(nèi)部處理操作部分)會(huì)出現(xiàn)線程安全的嫌疑。這種開發(fā)方式不用New出對(duì)象,所以很普遍。
開發(fā)方式二:應(yīng)該多是應(yīng)用在cs模式下,DAL在整個(gè)項(xiàng)目只會(huì)有一個(gè)對(duì)象存在,如果出現(xiàn)在B/S
我想不能兼容多種問題情況。而且也有線程安全的問題。
開發(fā)方式三:應(yīng)該是普遍使用的,能夠兼容各種問題,也不會(huì)有線程不安全的嫌疑出現(xiàn)。
我特意以“你怎么理解并使用靜態(tài)方法和實(shí)例化方法的?”這樣的問題詢問了多位程序員,他們開發(fā)的語言也不盡相同(c
、c++、java、c#)
以下是他們的回答:
張偉說:幾乎沒有區(qū)別,如果不需要實(shí)例化,就用靜態(tài)方法;如果為了穩(wěn)妥,就用實(shí)例方法,這樣才可調(diào)用其他實(shí)例方法和變量。
蕭遠(yuǎn)山說:靜態(tài)方法比較少用,因?yàn)樗谝粏?dòng)就實(shí)例化了,比較占資源,當(dāng)然,,配合單例模式還是比較好用的比較多的用在數(shù)據(jù)連接上,我避免使用的原則就是減少資源消耗。
張新波說:靜態(tài)方法意味著我在調(diào)用前不需要進(jìn)行對(duì)其所屬的類進(jìn)行new操作,我主要會(huì)在工具類里面用到靜態(tài)方法。
向詳說:靜態(tài)就是類的,實(shí)例就是對(duì)象的。靜態(tài)方法和實(shí)例方法的區(qū)別之處還有一個(gè)地方:靜態(tài)方法不需要依賴類當(dāng)中的屬性,能在這個(gè)方法中封閉的完成一個(gè)功能。實(shí)例方法更多的會(huì)使用到類當(dāng)中的屬性。
winson_張林說:最大的區(qū)別在于內(nèi)存。靜態(tài)方法在程序開始時(shí)生成內(nèi)存,實(shí)例方法在程序運(yùn)行中生成內(nèi)存
showlover說:
靜態(tài)方法與實(shí)例方法各有自己的用處...
是定義成靜態(tài)方法,還是定義成實(shí)例方法,還要看具體情況,比如方法本身與類型沒有太大的關(guān)系,可以定義成靜態(tài)方法..
用實(shí)例方法,當(dāng)然需要你先創(chuàng)建實(shí)例,才能調(diào)用實(shí)例方法,而靜態(tài)方法則不需要..
從性能上說,靜態(tài)方法效率要稍微高一些,但是它會(huì)常駐內(nèi)存...
一些情況下使用靜態(tài)方法是有好處的,因?yàn)閷?duì)于靜態(tài)方法無論你有多少個(gè)實(shí)例,內(nèi)存中要維護(hù)的一份拷貝。同時(shí),某些方法,確實(shí)使用靜態(tài)是比較恰當(dāng)?shù)?.
Q.yuhen說:
這個(gè)問題牽扯到的東西比較多,諸如設(shè)計(jì)模式等等。簡(jiǎn)單點(diǎn)說,靜態(tài)方法用來執(zhí)行無狀態(tài)的一個(gè)完整操作,實(shí)例方法則相反,它通常是一個(gè)完整邏輯的一部分,并且需要維護(hù)一定的狀態(tài)值。如果用內(nèi)存和效率來區(qū)分使用Static Method、Instance Method
就回到過去結(jié)構(gòu)化編程了。使用那種方法的根本出發(fā)點(diǎn)還是圍繞面向?qū)ο髞磉M(jìn)行的。
陳亮說:
靜態(tài)方法和全局函數(shù)差不多的,實(shí)例方法是一個(gè)類里面的方法。
如果從線程安全、性能、兼容性上來看也是選用實(shí)例化方法為宜。
我們?yōu)槭裁匆逊椒▍^(qū)分為:靜態(tài)方法和實(shí)例化方法?
如果我們繼續(xù)深入研究的話,就要脫離技術(shù)談理論了。早期的結(jié)構(gòu)化編程,幾乎所有的方法都是“靜態(tài)方法”,引入實(shí)例化方法概念是面向?qū)ο蟾拍畛霈F(xiàn)以后的事情了,區(qū)分靜態(tài)方法和實(shí)例化方法不能單單從性能上去理解,創(chuàng)建c++,java,c#這樣面向?qū)ο笳Z言的大師引入實(shí)例化方法一定不是要解決什么性能、內(nèi)存的問題,而是為了讓開發(fā)更加模式化、面向?qū)ο蠡_@樣說的話,靜態(tài)方法和實(shí)例化方式的區(qū)分是為了解決模式的問題。
拿別人一個(gè)例子說事:
比如說“人”這個(gè)類,每個(gè)人都有姓名、年齡、性別、身高等,這些屬性就應(yīng)該是非靜態(tài)的,因?yàn)槊總€(gè)人都的這些屬性都不相同;但人在生物學(xué)上屬于哪個(gè)門哪個(gè)綱哪個(gè)目等,這個(gè)屬性是屬于整個(gè)人類,所以就應(yīng)該是靜態(tài)的——它不依賴與某個(gè)特定的人,不會(huì)有某個(gè)人是“脊椎動(dòng)物門哺乳動(dòng)物綱靈長(zhǎng)目”而某個(gè)人卻是“偶蹄目”的。
Java靜態(tài)初始化,實(shí)例初始化以及構(gòu)造方法首先有三個(gè)概念需要了解:
一.靜態(tài)初始化:是指執(zhí)行靜態(tài)初始化塊里面的內(nèi)容。
二.實(shí)例初始化:是指執(zhí)行實(shí)例初始化塊里面的內(nèi)容。
三.構(gòu)造方法:一個(gè)名稱跟類的名稱一樣的方法,特殊在于不帶返回值。
我們先來看一段程序結(jié)果:
執(zhí)行結(jié)果:
this is static method~
this is static block
如果把
的注釋去掉的話,運(yùn)行結(jié)果為:
this is static method~
this is static block
初始化塊:0
this is Book's constructor~
執(zhí)行順序:(優(yōu)先級(jí)從高到低。)靜態(tài)代碼塊>main方法>實(shí)例初始化塊>構(gòu)造代碼塊>構(gòu)造方法。”
總結(jié):
僅從代碼執(zhí)行的角度來探討Java加載類、創(chuàng)建對(duì)象的過程,并沒有深入到JVM的機(jī)制中去。
1.一個(gè)對(duì)象第一次被創(chuàng)建時(shí),先要加載該對(duì)象所屬的類,即對(duì)應(yīng)的.class文件,當(dāng)然如果類已經(jīng)加載,再次創(chuàng)建該類的對(duì)象時(shí),就不再需要重新加載類了。而一個(gè)類加載的時(shí)候,有三個(gè)部分需要加載,一個(gè)是靜態(tài)變量,再然后是靜態(tài)方法,然后是靜態(tài)初始化塊。(見到第一次執(zhí)行結(jié)果就知道了,由于沒有創(chuàng)建實(shí)例所以初始化塊不執(zhí)行)
2.然后開始創(chuàng)建該類的實(shí)例了,當(dāng)然如果靜態(tài)方法跟靜態(tài)初始化對(duì)象中有對(duì)象的創(chuàng)建時(shí),就繼續(xù)加載該對(duì)象的類,當(dāng)然已經(jīng)加載了該對(duì)象的類的話就不需要再次加載了。那么對(duì)象實(shí)例的創(chuàng)建過程是什么呢?首先是成員變量的引入,然后是實(shí)例初始化塊,之后才是構(gòu)造方法,構(gòu)造方法執(zhí)行完成之后才算把這個(gè)對(duì)象給創(chuàng)建出來了。
在這個(gè)過程中,真正可以編寫執(zhí)行代碼的地方有三個(gè),靜態(tài)初始化、實(shí)例初始化以及構(gòu)造方法。從以上的分析中我們可以看到,這三個(gè)代碼塊的執(zhí)行順序是先類的靜態(tài)初始化,再實(shí)例初始化,最后執(zhí)行構(gòu)造方法。也就是說,靜態(tài)初始化是屬于類加載的過程,所以它只執(zhí)行一次,而實(shí)例初始化是每個(gè)對(duì)象創(chuàng)建時(shí)都會(huì)執(zhí)行一次,而構(gòu)造方法跟實(shí)例初始化其實(shí)也差不多,不過它在實(shí)例初始化之后執(zhí)行,而且構(gòu)造方法可以重載多個(gè),執(zhí)行哪個(gè)構(gòu)造方法是根據(jù)你的選擇來的。
可以把main () 函數(shù)加一條語句看看:
此時(shí)執(zhí)行結(jié)果為:
this is static method~
this is static block
初始化塊:0
this is Book's constructor~
初始化塊:1
this is Book's constructor~
這說明實(shí)例初始化是每個(gè)對(duì)象創(chuàng)建時(shí)都會(huì)執(zhí)行的。
總結(jié)
以上是生活随笔為你收集整理的java 静态方法与实例方法的区别_静态方法与实例方法的区分的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hutool 自定义excel_Huto
- 下一篇: java aio聊天_JAVA aio简