關於靜態與非靜態之詳細總結

2021-06-29 03:16:08 字數 2688 閱讀 7266

花費了些功夫,差不多搞明白了:

大家會看到有些地方不停重複出現——那就是你要找的東西

靜態和非靜態:

字段、函式成員的宣告中含static修飾符時是靜態成員,否則是非靜態成員(例項成員);

資料成員可以分靜態變數、非靜態變數兩種. 靜態成員屬於類,而非靜態成員(例項成員)屬於物件。對於類的資料成員來說,如果是靜態的,那麼他將是類的一部分,為所有例項共享,如果是非靜態的,則每個例項有乙份考貝。

類的非靜態成員屬於類的例項所有,每建立乙個類的例項都在記憶體中為非靜態成員開闢了一塊區域;而類的靜態成員屬於類所有,被這個類的所有例項所共享,無論這個類建立了多少個副本,乙個靜態成員在記憶體中只占有一塊區域。

假如以e.m形式訪問靜態成員,e必須為類;訪問例項成員,e必須是例項。

類的靜態欄位只分配乙個儲存單元,類的每個例項欄位都有單獨拷貝。

靜態函式成員中不能訪問例項成員,不能使用this;例項函式成員中可以訪問例項成員和靜態成員,可以使用this。

靜態成員:靜態類中的成員加入static修飾符,即是靜態成員.可以直接使用類名+靜態成員名訪問此靜態成員,因為靜態成員存在於記憶體,非靜態成員需要例項化才會分配記憶體,所以靜態成員不能訪問非靜態的成員..因為靜態成員存在於記憶體,所以非靜態成員可以直接訪問類中靜態的成員.

非成靜態員:所有沒有加static的成員都是非靜態成員,當類被例項化之後,可以通過例項化的類名進行訪問..非靜態成員的生存期決定於該類的生存期..而靜態成員則不存在生存期的概念,因為靜態成員始終駐留在內容中..

從語法上來講,靜態函式沒有this指標。由於沒有this指標,就不能通過物件來引用,只能通過類名引用,

在靜態函式內部也不能引用非靜態的成員變數。呼叫普通函式的時候,類例項的this指標是作為第乙個引數隱式傳給函式的。從這裡說,普通函式是依賴於類的例項的,沒有類例項就不能呼叫。而static函式沒有this這個隱含引數。所以呼叫它時不用依賴類例項。也就是可以採用classname::funname的方式呼叫。類靜態函式對於全域性函式來說有乙個好處就是可以使用類的private和protected成員(當他獲得類例項指標的時候,比如引數傳入)。

從抽象的語義上來講,靜態函式的動作就是屬於整個類的,不屬於某個具體的物件。

靜態和非靜態主要有以下差別:

1.從儲存的角度看,靜態變數和方法在靜態儲存區分配記憶體,而非靜態的在棧區或者堆上分配記憶體

2.從作用域來講,靜態變數在其作用域範圍記憶體在於整個程式的執行過程中,而非靜態變數的作用時間也是區域性的。

3.從使用角度來講,靜態變數和方法沒有this指標,只能通過類名引用。

4.對於類的資料成員來說,如果是靜態的,那麼他將是類的一部分,為所有例項共享,如果是非靜態的,則每個例項有乙份考貝。

乙個類中也可以包含靜態成員和非靜態成員,類中也包括靜態建構函式和非靜態建構函式..

對於類的資料成員來說,如果是靜態的,那麼他將是類的一部分,為所有例項共享,如果是非靜態的,則每個例項有乙份考貝。

靜態成員函式只有乙份拷貝,而普通成員函式在每個類物件中都有乙份拷貝。

static int id = 0;

sql = "select * from table where id=" + id;

static string aa(string str)

或者返回乙個dataset的靜態方法

static dataset aa(string str)

這個時候,在訪問量大的時候,程式出現了併發,會不會發生錯亂??我以前的專案使用的公用函式類中使用了大量的靜態方法,不過好在訪問量不大,一直沒有問題..在發這個文章之前,我查詢了msdn,csdn,搜尋了一些關於靜態成員的文章,但是都沒有乙個明確的說明..雖然,自己在專案中也測試了這麼長時間也沒有問題..但是總覺得有這個可能發生..

不知道大家是否在專案中碰到類似的疑惑呢??請有過這方面經驗的朋友指教..

答案:不說是否濫用,如果你出現衝突,說明你沒有理解靜態成員變數和靜態方法的區別,靜態方法本身只是一段**,不管怎麼呼叫他都不會出現問題。但靜態成員變數就不行了,他被所有使用者共享,如果乙個使用者改變了他,肯定會影響到別人,這就是常說的併發衝突問題,一般來說在修改共享成員變數時要lock!

關於靜態方法和例項方法的一些誤區。

一、    靜態方法常駐記憶體,例項方法不是,所以靜態方法效率高但佔記憶體。

事實上,方法都是一樣的,在載入時機和占用記憶體上,靜態方法和例項方法是一樣的,在型別第一次被使用時載入。呼叫的速度基本上沒有差別。

二、    靜態方法在堆上分配記憶體,例項方法在堆疊上。

事實上所有的方法都不可能在堆或者堆疊上分配記憶體,方法作為**是被載入到特殊的**記憶體區域,這個記憶體區域是不可寫的。

三、    例項方法需要先建立例項才可以呼叫,比較麻煩,靜態方法不用,比較簡單。

事實上如果乙個方法與他所在型別的例項無關,那麼它就應該是靜態的,決不會有人把它寫成例項方法。所以所有的例項方法都與例項有關,既然與例項有關,那麼建立例項就是必然的步驟,沒有麻煩簡單一說。實際上上你可以把所有的例項方法都寫成靜態的,將例項作為引數傳入即可。

有些方法看似與所在的例項無關,如icomparer.compare方法,但實際上每乙個實現這個介面的類都只會負責自己型別例項的比較,這是c#1.x規範中沒有泛型所帶來的歷史遺留問題。

大部分靜態方法是與類的例項有關的,如各種parse方法,他做成靜態的原因是他沒有例項作為引數。其他的大多是出於語義或者其他目的的考慮。

下面做了個簡單的例子

靜態與非靜態

一 靜態變數和例項變數的區別 1 靜態變數 由static修飾,在jvm中,靜態變數載入順序在物件之前,所以靜態變數不依賴物件的存在,可以不例項化物件的情況下使用類的靜態變數。通過上面的 可以看出,靜態變數可以在未例項化物件的時候使用,但是非靜態變數只能在例項化物件時候才能使用。執行結果為 30李四...

靜態與非靜態

什麼是靜態?被static修飾的為靜態,static可用來修飾變數 方法 內部類 塊。注意 1 static不能用來修飾外部類 介面 抽象類 抽象方法。2 介面中的變數可以不用明確的宣告為靜態的,但必須賦值,因為變數預設為public static final。3 介面中的方法不能被宣告為靜態的,介...

C 靜態與非靜態

public static class math 靜態類 靜態屬性 public static void add 靜態方法 注意 靜態類不能被例項化,沒有構造方法,成員全部為static 定義非靜態類 public class math 非靜態類 靜態屬性 public int myproperty...