电竞比分网-中国电竞赛事及体育赛事平台

分享

static 靜態(tài)方法 非靜態(tài)方法 靜態(tài)代碼塊

 一本正經(jīng)地胡鬧 2019-09-02

當(dāng)類的字節(jié)碼被加載到內(nèi)存時(shí),實(shí)例方法不會(huì)被分配入口地址,只有該類創(chuàng)建對(duì)象時(shí),類中的實(shí)例方法才分配入口地址,所以實(shí)例方法只能通過(guò)對(duì)象調(diào)用。

而類方法是當(dāng)類加載到內(nèi)存中,就分配了相應(yīng)的內(nèi)存地址,所以類方法不僅可以通過(guò)對(duì)象調(diào)用,也可以用類名調(diào)用。

靜態(tài)方法(Static Method)和非靜態(tài)方法(Non-Static Method)的區(qū)別總結(jié)如下:
1、靜態(tài)方法屬于類所有,類實(shí)例化前即可使用;
2、非靜態(tài)方法可以訪問(wèn)類中的任何成員,靜態(tài)方法只能訪問(wèn)類中的靜態(tài)成員。因?yàn)殪o態(tài)方法在類實(shí)例化前就可以使用,而類中的靜態(tài)變量在實(shí)例化之后才分配內(nèi)存;
4、static內(nèi)部只能出現(xiàn)static變量和其他static方法。而且static方法中還不能使用this等關(guān)鍵字,因?yàn)樗菍儆谡麄€(gè)類;
5、靜態(tài)方法效率上要比實(shí)例化高,靜態(tài)方法的缺點(diǎn)是不自動(dòng)進(jìn)行銷毀,而實(shí)例化的則可以做銷毀

靜態(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)存。
主要區(qū)別:靜態(tài)方法在創(chuàng)建對(duì)象前就可以使用了,非靜態(tài)方法必須通過(guò)new出來(lái)的對(duì)象調(diào)用。
如:

public class Per{
public static String getType(){
return "人類";
}
public String getName(){
return "張三";
}
}

上面這個(gè)類中的getType方法,在沒(méi)有new對(duì)象前這就可以這樣用:
String type=Per.getType();//type="人類";
而getName方法則不能這樣使用,編譯都不會(huì)通過(guò),getName必須這樣:
Per p=new Per();
String name=p.getName();//name="張三";
當(dāng)然,getType方法也可能通過(guò)對(duì)象調(diào)用:
String type=p.getType();//type="人類";

轉(zhuǎn)自 https://zhidao.baidu.com/question/1433773942389340379.html

靜態(tài)方法何時(shí)使用

  • 如果某些操作不依賴具體實(shí)例,那它就是靜態(tài)的,反之如果某些操作是依賴具體實(shí)例的(例如訪問(wèn)一個(gè)特定會(huì)員的名稱),那它就應(yīng)該是實(shí)例化的。

  • 靜態(tài)方法不用new對(duì)象可以直接調(diào)用

  • 1.與類相關(guān)與對(duì)象無(wú)關(guān) 
    2.不需要對(duì)象的“輕”方法 
    3.工廠方法

  • 如果某個(gè)方法是用頻率較高,或者方法本身通用性較強(qiáng),無(wú)需初始化類成員變量,則可以使用靜態(tài)方法,那樣方便,速度也快.

  • 可以直接拿來(lái)就用的方法,就算是靜態(tài)的.

  • 肯定不涉及具體對(duì)象,因?yàn)殪o態(tài)方法內(nèi),是無(wú)法直接使用任何非靜態(tài)成員的。

  • (1)制作工具類 
    (2)可以當(dāng)作"作局"對(duì)象或方法來(lái)使用

  • 靜態(tài)方法和實(shí)例方法是一樣的,在類型第一次被使用時(shí)加載。調(diào)用的速度基本上沒(méi)有差別。

  • 靜態(tài)方法不用創(chuàng)建實(shí)例就可調(diào)用,比較簡(jiǎn)單從面向?qū)ο蟮慕嵌壬蟻?lái)說(shuō),在抉擇使用實(shí)例化方法或靜態(tài)方法時(shí),應(yīng)該根據(jù)是否該方法和實(shí)例化對(duì)象具有邏輯上的相關(guān)性,如果是就應(yīng)該使用實(shí)例化對(duì)象  反之使用靜態(tài)方法

  • 不需要生成對(duì)象的 
    經(jīng)常頻繁使用的 
    工具類里的(如SqlHelper)

  • 適當(dāng)?shù)厥褂胹tatic方法本身并沒(méi)有什么,當(dāng)一個(gè)人從來(lái)不懂使用多態(tài)、接口設(shè)計(jì)時(shí),很自然地會(huì)濫用static方法。

  • 個(gè)人理解在多個(gè)類中需要調(diào)用并且是與對(duì)象無(wú)關(guān)的方法可設(shè)為靜態(tài)方法,方便調(diào)用。

  • 所有對(duì)象共有的方法

  • 再不關(guān)系到任何于特定對(duì)象相關(guān)的操作 
    比如學(xué)生的年齡就是學(xué)生的相關(guān)。 
    修改學(xué)生的年齡就不適合用靜態(tài)方法。 
    一般來(lái)說(shuō),如果你的方法里沒(méi)有用到this關(guān)鍵字, 
    那就適合用靜態(tài)方法

  • 通常通用的類中一些常用的方法可以設(shè)計(jì)為靜態(tài)類

  • 只要是沒(méi)有用到類的狀態(tài)信息,只從參數(shù)獲取信息的都可以為靜態(tài)的

  • 可以實(shí)現(xiàn)某些特殊的設(shè)計(jì)模式:如Singleton

  • 由于沒(méi)有this指針,可以把某些系統(tǒng)API的回調(diào)函數(shù)以靜態(tài)函數(shù)的形式封裝到類的內(nèi)部

  • 可以封裝某些算法,比如數(shù)學(xué)函數(shù),如ln,sin,tan等等,這些函數(shù)本就沒(méi)必要屬于任何一個(gè)對(duì)象,所以從類上調(diào)用感覺(jué)更好

  • 總之,從OOA/OOD的角度考慮,一切不需要實(shí)例化就可以有確定行為方式的函數(shù)都應(yīng)該設(shè)計(jì)成靜態(tài)的

  • 靜態(tài)方法與非靜態(tài)方法最明顯的區(qū)別就是如果某個(gè)方法是公共靜態(tài)的,那么可以直接通過(guò)類名.方法名的方法來(lái)調(diào)用,而公共實(shí)例方法則需要事先實(shí)例化對(duì)象,然后才能調(diào)用。

  這些各種說(shuō)法,基本上都是正確的。

 歡迎關(guān)注公眾號(hào)"Devin說(shuō)",會(huì)不定期更新技術(shù)知識(shí)。

轉(zhuǎn)自 https://www.cnblogs.com/devinzhang/archive/2012/04/27/2473570.html

靜態(tài)代碼塊

靜態(tài)代碼塊指 Java 類中的 static{...} 代碼塊,主要用于初始化類,為類的靜態(tài)變量賦初始值。

  • jvm在加載類時(shí)會(huì)執(zhí)行靜態(tài)代碼塊(即,類名.靜態(tài)變量,類名.靜態(tài)方法,實(shí)例化(new一個(gè)對(duì)象),都會(huì)執(zhí)行靜態(tài)代碼塊)。

  • 如果類中包含多個(gè)靜態(tài)代碼塊,jvm會(huì)按它們?cè)陬愔谐霈F(xiàn)的順序依次執(zhí)行它們,每個(gè)靜態(tài)代碼塊只會(huì)被執(zhí)行一次。

  • 與之對(duì)應(yīng)的是非靜態(tài)代碼塊{...}。每實(shí)例化一次,就會(huì)執(zhí)行一次。

注意:變量指基本數(shù)據(jù)類型非對(duì)象,局部變量不能被靜態(tài)修飾 

1、(靜態(tài))成員變量存放在data segment區(qū)(數(shù)據(jù)區(qū)),字符串常量也存放在該區(qū) 

2、非靜態(tài)變量,new出來(lái)的對(duì)象存放在堆內(nèi)存,所有局部變量和引用地址存放在棧內(nèi)存 

3、方法(包括靜態(tài)方法)存放在code segment(方法塊),存放代碼片段,且只存放一次


public class Cat {

    //private static int sid = 0;

    private int sid = 0;

    private String name; 

    int id;

    Cat(String name) {

        this.name = name;  

        id = sid++;

    }

    public void info(){

        System.out.println

               ("My name is "+name+" No."+id);

    }

    public static void main(String arg[]){

        //Cat.sid = 100;

        Cat mimi = new Cat("mimi");

        mimi.sid = 2000;

        Cat pipi = new Cat("pipi");

        mimi.info(); 

        pipi.info();

    }

}

靜態(tài)方法和實(shí)例方法區(qū)別及使用場(chǎng)景

從實(shí)際項(xiàng)目開(kāi)發(fā)說(shuō)起,這里有開(kāi)發(fā)項(xiàng)目的三種方式: 

開(kāi)發(fā)項(xiàng)目中把BLL和DAL分開(kāi),在BLL調(diào)用DAL的代碼。 

一、在DAL中使用靜態(tài)方法,不創(chuàng)建實(shí)例直接調(diào)用(大概有很多人都使用這種方式開(kāi)發(fā) ) 

class DAL 

public static string GetUserName(…); 

在BLL中調(diào)用: 

DAL.GetUserName(); 

二、在DAL中使用實(shí)例方法,采用靜態(tài)成員模式(或Singleton)通過(guò)實(shí)例來(lái)調(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();

開(kāi)發(fā)方式一:我以為在一些情況下(比如 調(diào)用多個(gè)數(shù)據(jù)庫(kù)、GetUserName(…)內(nèi)部處理操作部分)會(huì)出現(xiàn)線程安全的嫌疑。這種開(kāi)發(fā)方式不用New出對(duì)象,所以很普遍。 

開(kāi)發(fā)方式二:應(yīng)該多是應(yīng)用在cs模式下,DAL在整個(gè)項(xiàng)目只會(huì)有一個(gè)對(duì)象存在,如果出現(xiàn)在B/S 我想不能兼容多種問(wèn)題情況。而且也有線程安全的問(wèn)題。 

開(kāi)發(fā)方式三:應(yīng)該是普遍使用的,能夠兼容各種問(wèn)題,也不會(huì)有線程不安全的嫌疑出現(xiàn)。

特別說(shuō)明一下:在MS的pet3.0以前的版本 都采用了方式二,而到pet3.0和以后的版本 都采用了方式三,而且特別在開(kāi)發(fā)說(shuō)明文檔中明確的解釋了一下。我想應(yīng)該是從兼容性上考慮的,從性能上方式二并不比方式三真正的高多少。

我特意以“你怎么理解并使用靜態(tài)方法和實(shí)例化方法的?”這樣的問(wèn)題詢問(wèn)了多位程序員,他們開(kāi)發(fā)的語(yǔ)言也不盡相同(c 、c++、java、c#) 

以下是他們的回答:

海龍說(shuō): 

公用的方法,而且是一些零散的 一般用靜態(tài)方法 

張偉說(shuō): 

幾乎沒(méi)有區(qū)別,如果不需要實(shí)例化,就用靜態(tài)方法;如果為了穩(wěn)妥,就用實(shí)例方法,這樣才可調(diào)用其他實(shí)例方法和變量 。 

蕭遠(yuǎn)山說(shuō): 

靜態(tài)方法比較少用,因?yàn)樗谝粏?dòng)就實(shí)例化了,比較占資源,當(dāng)然,,配合單例模式還是比較好用的 

比較多的用在數(shù)據(jù)連接上,我避免使用的原則就是減少資源消耗。 

張新波說(shuō): 

靜態(tài)方法意味著我在調(diào)用前不需要進(jìn)行對(duì)其所屬的類進(jìn)行new操作,我主要會(huì)在工具類里面用到靜態(tài)方法。

向詳說(shuō): 

靜態(tài)就是類的,實(shí)例就是對(duì)象的。 

靜態(tài)方法和實(shí)例方法的區(qū)別之處還有一個(gè)地方:靜態(tài)方法不需要依賴類當(dāng)中的屬性,能在這個(gè)方法中封閉的完成一個(gè)功能。實(shí)例方法更多的會(huì)使用到類當(dāng)中的屬性。 

winson_張林說(shuō): 

最大的區(qū)別在于內(nèi)存。 

靜態(tài)方法在程序開(kāi)始時(shí)生成內(nèi)存,實(shí)例方法在程序運(yùn)行中生成內(nèi)存, 

所以靜態(tài)方法可以直接調(diào)用,實(shí)例方法要先成生實(shí)例,通過(guò)實(shí)例調(diào)用方法,靜態(tài)速度很快,但是多了會(huì)占內(nèi)存。 

任何語(yǔ)言都是對(duì)內(nèi)存和磁盤的操作,至于是否面向?qū)ο?只是軟件層的問(wèn)題,底層都是一樣的,只是實(shí)現(xiàn)方法不同。 

靜態(tài)內(nèi)存是連續(xù)的,因?yàn)槭窃诔绦蜷_(kāi)始時(shí)就生成了,而實(shí)例申請(qǐng)的是離散的空間,所以當(dāng)然沒(méi)有靜態(tài)方法快, 

而且靜態(tài)內(nèi)存是有限制的,太多了程序會(huì)啟動(dòng)不了。 

showlover說(shuō): 

靜態(tài)方法與實(shí)例方法各有自己的用處… 

是定義成靜態(tài)方法,還是定義成實(shí)例方法,還要看具體情況,比如方法本身與類型沒(méi)有太大的關(guān)系,可以定義成靜態(tài)方法.. 

用實(shí)例方法,當(dāng)然需要你先創(chuàng)建實(shí)例,才能調(diào)用實(shí)例方法,而靜態(tài)方法則不需要.. 

從性能上說(shuō),靜態(tài)方法效率要稍微高一些,但是它會(huì)常駐內(nèi)存… 

一些情況下使用靜態(tài)方法是有好處的,因?yàn)閷?duì)于靜態(tài)方法無(wú)論你有多少個(gè)實(shí)例, 

內(nèi)存中要維護(hù)的一份拷貝。同時(shí),某些方法,確實(shí)使用靜態(tài)是比較恰當(dāng)?shù)?. 

Q.yuhen說(shuō): 

這個(gè)問(wèn)題牽扯到的東西比較多,諸如設(shè)計(jì)模式等等。簡(jiǎn)單點(diǎn)說(shuō),靜態(tài)方法用來(lái)執(zhí)行無(wú)狀態(tài)的一個(gè)完整操作,實(shí)例方法則相反,它通常是一個(gè)完整邏輯的一部分,并且需要維護(hù)一定的狀態(tài)值。 

如果用內(nèi)存和效率來(lái)區(qū)分使用Static Method、Instance Method 就回到過(guò)去結(jié)構(gòu)化編程了。使用那種方法的根本出發(fā)點(diǎn)還是圍繞面向?qū)ο髞?lái)進(jìn)行的。

陳亮說(shuō): 

靜態(tài)方法和全局函數(shù)差不多的,實(shí)例方法是一個(gè)類里面的方法。

總結(jié):大家對(duì)這個(gè)問(wèn)題都有一個(gè)共識(shí):那就是實(shí)例化方法更多被使用和穩(wěn)妥,靜態(tài)方法少使用。

有時(shí)候我們對(duì)靜態(tài)方法和實(shí)例化方法會(huì)有一些誤解。 

1、大家都以為“ 靜態(tài)方法常駐內(nèi)存,實(shí)例方法不是,所以靜態(tài)方法效率高但占內(nèi)存。” 

事實(shí)上,他們都是一樣的,在加載時(shí)機(jī)和占用內(nèi)存上,靜態(tài)方法和實(shí)例方法是一樣的,在類型第一次被使用時(shí)加載。調(diào)用的速度基本上沒(méi)有差別。 

2、大家都以為“ 靜態(tài)方法在堆上分配內(nèi)存,實(shí)例方法在堆棧上” 

事實(shí)上所有的方法都不可能在堆或者堆棧上分配內(nèi)存,方法作為代碼是被加載到特殊的代碼內(nèi)存區(qū)域,這個(gè)內(nèi)存區(qū)域是不可寫(xiě)的。 

方法占不占用更多內(nèi)存,和它是不是static沒(méi)什么關(guān)系。 

因?yàn)樽侄问怯脕?lái)存儲(chǔ)每個(gè)實(shí)例對(duì)象的信息的,所以字段會(huì)占有內(nèi)存,并且因?yàn)槊總€(gè)實(shí)例對(duì)象的狀態(tài)都不一致(至少不能認(rèn)為它們是一致的),所以每個(gè)實(shí)例對(duì)象的所有字段都會(huì)在內(nèi)存中有一分拷貝,也因?yàn)檫@樣你才能用它們來(lái)區(qū)分你現(xiàn)在操作的是哪個(gè)對(duì)象。 

但方法不一樣,不論有多少個(gè)實(shí)例對(duì)象,它的方法的代碼都是一樣的,所以只要有一份代碼就夠了。因此無(wú)論是static還是non-static的方法,都只存在一份代碼,也就是只占用一份內(nèi)存空間。 

同樣的代碼,為什么運(yùn)行起來(lái)表現(xiàn)卻不一樣?這就依賴于方法所用的數(shù)據(jù)了。主要有兩種數(shù)據(jù)來(lái)源,一種就是通過(guò)方法的參數(shù)傳進(jìn)來(lái),另一種就是使用class的成員變量的值…… 

3、大家都以為“實(shí)例方法需要先創(chuàng)建實(shí)例才可以調(diào)用,比較麻煩,靜態(tài)方法不用,比較簡(jiǎn)單” 

事實(shí)上如果一個(gè)方法與他所在類的實(shí)例對(duì)象無(wú)關(guān),那么它就應(yīng)該是靜態(tài)的,而不應(yīng)該把它寫(xiě)成實(shí)例方法。所以所有的實(shí)例方法都與實(shí)例有關(guān),既然與實(shí)例有關(guān),那么創(chuàng)建實(shí)例就是必然的步驟,沒(méi)有麻煩簡(jiǎn)單一說(shuō)。 

當(dāng)然你完全可以把所有的實(shí)例方法都寫(xiě)成靜態(tài)的,將實(shí)例作為參數(shù)傳入即可,一般情況下可能不會(huì)出什么問(wèn)題。 

從面向?qū)ο蟮慕嵌壬蟻?lái)說(shuō),在抉擇使用實(shí)例化方法或靜態(tài)方法時(shí),應(yīng)該根據(jù)是否該方法和實(shí)例化對(duì)象具有邏輯上的相關(guān)性,如果是就應(yīng)該使用實(shí)例化對(duì)象 反之使用靜態(tài)方法。這只是從面向?qū)ο蠼嵌壬蟻?lái)說(shuō)的。 

如果從線程安全、性能、兼容性上來(lái)看 也是選用實(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(yǔ)言的大師引入實(shí)例化方法一定不是要解決什么性能、內(nèi)存的問(wèn)題,而是為了讓開(kāi)發(fā)更加模式化、面向?qū)ο蠡?。這樣說(shuō)的話,靜態(tài)方法和實(shí)例化方式的區(qū)分是為了解決模式的問(wèn)題。 

拿別人一個(gè)例子說(shuō)事: 

比如說(shuō)“人”這個(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è)人卻是“偶蹄目”的。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多