花費了些功夫,差不多搞明白了:
大家會看到有些地方不停重複出現——那就是你要找的東西
靜態和非靜態:
字段、函式成員的宣告中含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...