當(dāng)類的字節(jié)碼被加載到內(nèi)存時(shí),實(shí)例方法不會(huì)被分配入口地址,只有該類創(chuàng)建對(duì)象時(shí),類中的實(shí)例方法才分配入口地址,所以實(shí)例方法只能通過對(duì)象調(diào)用。 而類方法是當(dāng)類加載到內(nèi)存中,就分配了相應(yīng)的內(nèi)存地址,所以類方法不僅可以通過對(duì)象調(diào)用,也可以用類名調(diào)用。 靜態(tài)方法(Static Method)和非靜態(tài)方法(Non-Static Method)的區(qū)別總結(jié)如下: 靜態(tài)方法在類裝載的時(shí)候被裝載到內(nèi)存(Memory),不自動(dòng)進(jìn)行銷毀,會(huì)一直存在于內(nèi)存中,直到JVM關(guān)閉。 非靜態(tài)方法在實(shí)例化后才會(huì)分配內(nèi)存,當(dāng)實(shí)例對(duì)象被JVM 回收之后,也跟著消失,不會(huì)常駐內(nèi)存。 6、靜態(tài)方法和靜態(tài)變量創(chuàng)建后始終使用同一塊內(nèi)存,而使用實(shí)例的方式會(huì)創(chuàng)建多個(gè)內(nèi)存。
上面這個(gè)類中的getType方法,在沒有new對(duì)象前這就可以這樣用: 轉(zhuǎn)自 https://zhidao.baidu.com/question/1433773942389340379.html 靜態(tài)方法何時(shí)使用
這些各種說法,基本上都是正確的。 歡迎關(guān)注公眾號(hào)"Devin說",會(huì)不定期更新技術(shù)知識(shí)。 轉(zhuǎn)自 https://www.cnblogs.com/devinzhang/archive/2012/04/27/2473570.html 靜態(tài)代碼塊靜態(tài)代碼塊指 Java 類中的 static{...} 代碼塊,主要用于初始化類,為類的靜態(tài)變量賦初始值。
注意:變量指基本數(shù)據(jù)類型非對(duì)象,局部變量不能被靜態(tài)修飾 1、(靜態(tài))成員變量存放在data segment區(qū)(數(shù)據(jù)區(qū)),字符串常量也存放在該區(qū) 2、非靜態(tài)變量,new出來的對(duì)象存放在堆內(nèi)存,所有局部變量和引用地址存放在棧內(nèi)存 3、方法(包括靜態(tài)方法)存放在code segment(方法塊),存放代碼片段,且只存放一次 ![]()
![]() 靜態(tài)方法和實(shí)例方法區(qū)別及使用場(chǎng)景從實(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ù)庫、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)。 特別說明一下:在MS的pet3.0以前的版本 都采用了方式二,而到pet3.0和以后的版本 都采用了方式三,而且特別在開發(fā)說明文檔中明確的解釋了一下。我想應(yīng)該是從兼容性上考慮的,從性能上方式二并不比方式三真正的高多少。 我特意以“你怎么理解并使用靜態(tài)方法和實(shí)例化方法的?”這樣的問題詢問了多位程序員,他們開發(fā)的語言也不盡相同(c 、c++、java、c#) 以下是他們的回答:
有時(shí)候我們對(duì)靜態(tài)方法和實(shí)例化方法會(huì)有一些誤解。 1、大家都以為“ 靜態(tài)方法常駐內(nèi)存,實(shí)例方法不是,所以靜態(tài)方法效率高但占內(nèi)存?!?nbsp; 事實(shí)上,他們都是一樣的,在加載時(shí)機(jī)和占用內(nèi)存上,靜態(tài)方法和實(shí)例方法是一樣的,在類型第一次被使用時(shí)加載。調(diào)用的速度基本上沒有差別。 2、大家都以為“ 靜態(tài)方法在堆上分配內(nèi)存,實(shí)例方法在堆棧上” 事實(shí)上所有的方法都不可能在堆或者堆棧上分配內(nèi)存,方法作為代碼是被加載到特殊的代碼內(nèi)存區(qū)域,這個(gè)內(nèi)存區(qū)域是不可寫的。 方法占不占用更多內(nèi)存,和它是不是static沒什么關(guān)系。 因?yàn)樽侄问怯脕泶鎯?chǔ)每個(gè)實(shí)例對(duì)象的信息的,所以字段會(huì)占有內(nèi)存,并且因?yàn)槊總€(gè)實(shí)例對(duì)象的狀態(tài)都不一致(至少不能認(rèn)為它們是一致的),所以每個(gè)實(shí)例對(duì)象的所有字段都會(huì)在內(nèi)存中有一分拷貝,也因?yàn)檫@樣你才能用它們來區(qū)分你現(xiàn)在操作的是哪個(gè)對(duì)象。 但方法不一樣,不論有多少個(gè)實(shí)例對(duì)象,它的方法的代碼都是一樣的,所以只要有一份代碼就夠了。因此無論是static還是non-static的方法,都只存在一份代碼,也就是只占用一份內(nèi)存空間。 同樣的代碼,為什么運(yùn)行起來表現(xiàn)卻不一樣?這就依賴于方法所用的數(shù)據(jù)了。主要有兩種數(shù)據(jù)來源,一種就是通過方法的參數(shù)傳進(jìn)來,另一種就是使用class的成員變量的值…… 3、大家都以為“實(shí)例方法需要先創(chuàng)建實(shí)例才可以調(diào)用,比較麻煩,靜態(tài)方法不用,比較簡(jiǎn)單” 事實(shí)上如果一個(gè)方法與他所在類的實(shí)例對(duì)象無關(guān),那么它就應(yīng)該是靜態(tài)的,而不應(yīng)該把它寫成實(shí)例方法。所以所有的實(shí)例方法都與實(shí)例有關(guān),既然與實(shí)例有關(guān),那么創(chuàng)建實(shí)例就是必然的步驟,沒有麻煩簡(jiǎn)單一說。 當(dāng)然你完全可以把所有的實(shí)例方法都寫成靜態(tài)的,將實(shí)例作為參數(shù)傳入即可,一般情況下可能不會(huì)出什么問題。 從面向?qū)ο蟮慕嵌壬蟻碚f,在抉擇使用實(shí)例化方法或靜態(tài)方法時(shí),應(yīng)該根據(jù)是否該方法和實(shí)例化對(duì)象具有邏輯上的相關(guān)性,如果是就應(yīng)該使用實(shí)例化對(duì)象 反之使用靜態(tài)方法。這只是從面向?qū)ο蠼嵌壬蟻碚f的。 如果從線程安全、性能、兼容性上來看 也是選用實(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è)人卻是“偶蹄目”的。 |
|