『壹』 類的靜態成員和非靜態成員有何區別
非靜態成員也叫成員變數,二者區別如下 :
1、名稱上的區別
成員變數也叫實例變數;靜態變數也叫類變數。
2、內存存儲的區別
成員變數存儲到堆內存的對象中,靜態變數存儲到方法區的靜態區中。
3、生命周期不同
成員變數隨著對象的出現而出現,隨著對象的消失而消失。靜態變數隨著類的出現而出現,隨著類的消失而消失。
『貳』 靜態成員和非靜態成員的區別
數據成員可以分靜態變數、非靜態變數兩種.
靜態成員:靜態類中的成員加入static修飾符,即是靜態成員.可以直接使用類名+靜態成員名訪問此靜態成員,因為靜態成員存在於內存,非靜態成員需要實例化才會分配內存,所以靜態成員不能訪問非靜態的成員..因為靜態成員存在於內存,所以非靜態成員可以直接訪問類中靜態的成員.
非成靜態員:所有沒有加Static的成員都是非靜態成員,當類被實例化之後,可以通過實例化的類名進行訪問..非靜態成員的生存期決定於該類的生存期..而靜態成員則不存在生存期的概念,因為靜態成員始終駐留在內容中..
一個類中也可以包含靜態成員和非靜態成員,類中也包括靜態構造函數和非靜態構造函數..
對於winApp來說,靜態成員對於程序員本身省了很多事,而且因為靜態成員駐留內存,在方法與方法之間傳遞共享數據的時候,所以靜態成員成了我的首選..但是不要因為方便,大量使用,尤其是在內存緊張或者
用靜態方法操作一些共享值的時候.或者要寫多用戶系統的時候,要慎之又慎.比如:
static int id = 0;
sql = "select * from table where id=" + id;
如果這樣寫的話,在單機測試的時候沒有問題,但是在多人同時對數據進行測試的時候,就會有問題了.假如,A用戶訪問他的id是20,則id的值在內存中為20,而此時B用戶訪問,他的id是30,則id在內存中的值是30..A用戶的id值則被更改了..如果此時你將這個方法用非靜態成員來寫,則不會出現這樣的情況..因為非靜態成員是你聲明的時候,實例化的時候才會分配內存..所以A用戶訪問的時候,App會因為A實例化而給A用戶的請求分配內存..而B用戶訪問的時候也一樣會因為B用戶的訪問而分配內存..所以兩個用戶訪問的是不同的內存塊..所以不會出現數據覆蓋和錯亂的現象...
我想這樣的情況應該能很好的說明靜態變數和非靜態成員的區別..
相對於webApp而言,在winApp下使用static的時候要比webApp下考慮的因素要少的多,因為webApp本來就是一個多用戶的系統,所以使用static的時候更應該小心..
而我對static在webApp下的使用存在一個疑問,如果一個靜態方法,例如:
static string aa(string str){
//經過一系列操作..
return str;
}
或者返回一個DataSet的靜態方法
static DataSet aa(string str){
//經過一系列操作..
return DataSet;
}
這個時候,在訪問量大的時候,程序出現了並發,會不會發生錯亂??我以前的項目使用的公用函數類中使用了大量的靜態方法,不過好在訪問量不大,一直沒有問題..在發這個文章之前,我查找了MSDN,CSDN,搜索了一些關於靜態成員的文章,但是都沒有一個明確的說明..雖然,自己在項目中也測試了這么長時間也沒有問題..但是總覺得有這個可能發生..
不知道大家是否在項目中碰到類似的疑惑呢??請有過這方面經驗的朋友指教..
答案:
不說是否濫用,如果你出現沖突,說明你沒有理解靜態成員變數和靜態方法的區別,靜態方法本身只是一段代碼,不管怎麼調用他都不會出現問題。但靜態成員變數就不行了,他被所有用戶共享,如果一個用戶改變了他,肯定會影響到別人,這就是常說的並發沖突問題,一般來說在修改共享成員變數時要lock!
關於靜態方法和實例方法的一些誤區。
一、 靜態方法常駐內存,實例方法不是,所以靜態方法效率高但占內存。
事實上,方法都是一樣的,在載入時機和佔用內存上,靜態方法和實例方法是一樣的,在類型第一次被使用時載入。調用的速度基本上沒有差別。
二、 靜態方法在堆上分配內存,實例方法在堆棧上。
事實上所有的方法都不可能在堆或者堆棧上分配內存,方法作為代碼是被載入到特殊的代碼內存區域,這個內存區域是不可寫的。
三、 實例方法需要先創建實例才可以調用,比較麻煩,靜態方法不用,比較簡單。
事實上如果一個方法與他所在類型的實例無關,那麼它就應該是靜態的,決不會有人把它寫成實例方法。所以所有的實例方法都與實例有關,既然與實例有關,那麼創建實例就是必然的步驟,沒有麻煩簡單一說。實際上上你可以把所有的實例方法都寫成靜態的,將實例作為參數傳入即可。
有些方法看似與所在的實例無關,如IComparer.Compare方法,但實際上每一個實現這個介面的類都只會負責自己類型實例的比較,這是C#1.x規范中沒有泛型所帶來的歷史遺留問題。
大部分靜態方法是與類的實例有關的,如各種Parse方法,他做成靜態的原因是他沒有實例作為參數。其他的大多是出於語義或者其他目的的考慮。
『叄』 c#靜態變數和非靜態變數的區別
使用上,靜態變數會駐存,非靜態變數不會。靜態可以類比我全局變數。
內存上,編譯後,非靜態變數不佔用磁碟空間,運行時,在堆棧區申請內存
靜態變數如果初始化了,編譯後佔用磁碟控制項,程序的data區。如果沒有初始化,則運行時申請內存。
『肆』 什麼叫靜態變數與動態變數的差別在哪
非靜態變數:此變數在其所在子程序開始被執行前自動分配存儲空間並初始化,在所在子程序執行完畢後自動釋放所分配的存儲空間。也就是說,變數的存儲空間僅在其所在子程序執行過程中存在;
靜態變數:此變數與全局、程序集變數一樣,被分配給在程序運行期間永久存在的存儲空間並僅在應用程序啟動運行前被初始化一次。
『伍』 Java語言中的靜態變數和非靜態變數之間有什麼區別
用static修飾的變數叫靜態變數。靜態變數不需要new出對象引用來調用,它可以直接用類名直接調用。當然用對象引用也能調它,只是不需要。
非靜態變數則必須用對象引用進行調用。
靜態變數在內存空間中只有一份,也永遠只有一份。大家共享。
非靜態變數只要new出一個對象引用就會在內存中分配一份空間給它。
並且他兩的存放地點不一樣,靜態變數存放在棧空間。非靜態變數存放在堆空間里。
才子_輝祝您愉快!
『陸』 靜態變數和非靜態變數以及局部變數在堆棧中的活動
靜態變數是屬性類的,被所有類的實例所共有,而非靜態變數是屬於實例的,最後的局部變數僅僅在方法內起作用,如上面的變數c僅僅在main方法中起作用。
『柒』 static變數存儲在哪裡
該變數在全局數據區分配內存;
未經初始化的靜態全局變數會被程序自動初始化為0(自動變數的值是隨機的,除非它被顯式初始化);
靜態全局變數在聲明它的整個文件都是可見的,而在文件之外是不可見的;
靜態變數都在全局數據區分配內存,包括後面將要提到的靜態局部變數。對於一個完整的程序,在內存中的
代碼區,全局數據區,堆區,棧區
一般程序的由new產生的動態數據存放在堆區,函數內部的自動變數存放在棧區。自動變數一般會隨著函數的退出而釋放空間,靜態數據(即使是函數內部的靜態局部變數)也存放在全局數據區。全局數據區的數據並不會因為函數的退出而釋放空間。細心的讀者可能會發現,Example 1中的代碼中將
static int n; //定義靜態全局變數
改為
int n; //定義全局變數
程序照樣正常運行。
的確,定義全局變數就可以實現變數在文件中的共享,但定義靜態全局變數還有以下好處:
靜態全局變數不能被其它文件所用;
其它文件中可以定義相同名字的變數,不會發生沖突;
『捌』 C語言中變數的存儲類型有哪幾種,存儲方式哪幾種謝嘍
在C語言中,對變數的存儲類型說明有以下四種:
1、auto 自動變數
2、register 寄存器變數
3、extern 外部變數
4、static 靜態變數
所謂存儲類型是指變數佔用內存空間的方式,也稱為存儲方式。
變數的存儲方式可分為「靜態存儲」和「動態存儲」兩種。
1、靜態存儲變數通常是在變數定義時就在存儲單元並一直保持不變,直至整個程序結束。
2、動態存儲變數是在程序執行過程中,使用它時才分配存儲單元,使用完畢立即釋放。典型的例子是函數的形式參數,在函數定義時並不給形參分配存儲單元,只是在函數被調用時,才予以分配,調用函數完畢立即釋放。
如果一個函數被多次調用,則反復地分配、釋放形參變數的存儲單元。從以上分析可知,靜態存儲變數是一直存在的,而動態存儲變數則時而存在時而消失。
(8)靜態變數和非靜態變數的存儲擴展閱讀:
變數根據定義的位置的不同的生命周期,具有不同的作用域,作用域可分為6種:全局作用域,局部作用域,語句作用域,類作用域,命名空間作用域和文件作用域。
一、從作用域看:
1、全局變數具有全局作用域。全局變數只需在一個源文件中定義,就可以作用於所有的源文件。當然,其他不包含全局變數的定義的源文件需要用extern關鍵字再次聲明這個全局變數。
2、靜態局部變數具有局部作用域,它只被初始化一次,自從第一次被初始化直到程序運行結束一直存在,它和全局變數的區別在於全局變數對所有函數都是可見的,而靜態局部變數只對定義自己的函數體始終可見。
3、局部變數也只有局部作用域,它是自動對象(auto),它在程序運行期間不是一直存在,而是只在函數執行期間存在,函數的一次調用執行結束後,變數被撤銷,其所佔用的內存也被收回。
4、靜態全局變數也具有全局作用域,它與全局變數的區別在於如果程序包含多個文件的話,它作用於定義它文件里,不能作用到其他文件里,即被static關鍵字修飾過的變數具有文件作用域。這樣即使兩個不同的源文件都定義了相同名字的靜態全局變數,它們也是不同的變數。
二、從分配空間看:
全局變數,靜態局部變數,靜態全局變數都在靜態存儲區分配空間,而局部變數在棧里分配空間。
全局變數本身就是靜態存儲方式,靜態全局變數當然也是靜態存儲方式。這兩者在存儲方式上並無不同。這兩者的區別雖在於非靜態全局變數的作用域是整個源程序,當一個源程序由多個源文件組成時,非靜態的全局變數在各個源文件中都是有效的。
而靜態全局變數則限制了其作用域,即只在定義該變數的源文件內有效,在同一個源程序的其他源文件中不能使用它。由於靜態全局變數的作用域局限於一個源文件內,只能為該源文件內的函數公用,因此可以避免在其他源文件中引起錯誤。
1、靜態變數會放在程序的靜態數據存儲區(全局可見)中,這樣可以在下一次調用的時候還可以保持原來的賦值。這一點是它與堆棧變數和堆變數的區別。
2、變數用static告知編譯器,自己僅僅在變數的作用范圍內可見。這一點是它與全局變數的區別。
參考資料來源:網路-變數-存儲類型
『玖』 java里static變數和非static變數有什麼區別
static 修飾的變數稱為類變數或全局變數或成員變數,在類被載入的時候成員變數即被初始化,與類關聯,只要類存在,static變數就存在。
一個static變數單獨劃分一塊存儲空間,不與具體的對象綁定在一起,該存儲空間被類的各個對象所共享。
也就是說當聲明一個對象是,並不產生static變數的拷貝,而是該類所有的實例對象共用同一個static變數。
非static修飾的成員變數是在對象new出來的時候劃分存儲空間,是與具體的對象綁定的,該成員變數僅為當前對象所擁有的。
對象在引用成員變數是直接通過類名.變數名調用,對象在引用實例變數時只能通過對象名.變數名調用。
在類中調用成員變數時直接調用或者以類名.變數名方式調用,實例變數則用this或者直接調用。
『拾』 java中靜態變數和非靜態變數是怎麼區分的
靜態變數的類型說明符是static。 靜態變數當然是屬於靜態存儲方式,但是屬於靜態存儲方式的量不一定就是靜態變數, 例如外部變數雖屬於靜態存儲方式,但不一定是靜態變數,必須由 static加以定義後才能成為靜態外部變數,或稱靜態全局變數。 對於自動變數,它屬於動態存儲方式。 但是也可以用static定義它為靜態自動變數,或稱靜態局部變數,從而成為靜態存儲方式。
由此看來, 一個變數可由static進行再說明,並改變其原有的存儲方式。
1. 靜態局部變數
在局部變數的說明前再加上static說明符就構成靜態局部變數。
例如:
static int a,b;
static float array[5]={1,2,3,4,5};
靜態局部變數屬於靜態存儲方式,它具有以下特點:
(1)靜態局部變數在函數內定義,但不象自動變數那樣,當調用時就存在,退出函數時就消失。靜態局部變數始終存在著,也就是說它的生存期為整個源程序。
(2)靜態局部變數的生存期雖然為整個源程序,但是其作用域仍與自動變數相同,即只能在定義該變數的函數內使用該變數。退出該函數後, 盡管該變數還繼續存在,但不能使用它。
(3)允許對構造類靜態局部量賦初值。若未賦以初值,則由系統自動賦以0值。
(4)對基本類型的靜態局部變數若在說明時未賦以初值,則系統自動賦予0值。而對自動變數不賦初值,則其值是不定的。 根據靜態局部變數的特點, 可以看出它是一種生存期為整個源程序的量。雖然離開定義它的函數後不能使用,但如再次調用定義它的函數時,它又可繼續使用, 而且保存了前次被調用後留下的值。 因此,當多次調用一個函數且要求在調用之間保留某些變數的值時,可考慮採用靜態局部變數。雖然用全局變數也可以達到上述目的,但全局變數有時會造成意外的副作用,因此仍以採用局部靜態變數為宜
2.靜態全局變數
全局變數(外部變數)的說明之前再冠以static 就構成了靜態的全局變數。全局變數本身就是靜態存儲方式, 靜態全局變數當然也是靜態存儲方式。 這兩者在存儲方式上並無不同。這兩者的區別雖在於非靜態全局變數的作用域是整個源程序, 當一個源程序由多個源文件組成時,非靜態的全局變數在各個源文件中都是有效的。 而靜態全局變數則限制了其作用域, 即只在定義該變數的源文件內有效, 在同一源程序的其它源文件中不能使用它。由於靜態全局變數的作用域局限於一個源文件內,只能為該源文件內的函數公用, 因此可以避免在其它源文件中引起錯誤。從以上分析可以看出, 把局部變數改變為靜態變數後是改變了它的存儲方式即改變了它的生存期。把全局變數改變為靜態變數後是改變了它的作用域, 限制了它的使用范圍。因此static 這個說明符在不同的地方所起的作用是不同的。應予以注意。
靜態變數
除范圍之外,變數還有存活期,在這一期間變數能夠保持它們的值。在應用程序的存活期內一直保持模塊級變數和公用變數的值。但是,對於 Dim 聲明的局部變數以及聲明局部變數的過程,僅當過程在執行時這些局部變數才存在。通常,當一個過程執行完畢,它的局部變數的值就已經不存在,而且變數所佔據的內存也被釋放。當下一次執行該過程時,它的所有局部變數將重新初始化。
但可將局部變數定義成靜態的,從而保留變數的值。在過程內部用 Static 關鍵字聲明一個或多個變數,其用法和 Dim 語句完全一樣:
Static Depth
例如,下面的函數將存儲在靜態變數 Accumulate 中的以前的運營總值與一個新值相加,以計算運營總值。
Function RunningTotal (num)
Static ApplesSold
ApplesSold = ApplesSold + num
RunningTotal = ApplesSold
End Function
如果用 Dim 而不用 Static 聲明 ApplesSold,則以前的累計值不會通過調用函數保留下來,函數只會簡單地返回調用它的那個相同值。
在模塊的聲明段聲明 ApplesSold,並使它成為模塊級變數,由此也會收到同樣效果。但是,這種方法一旦改變變數的范圍,過程就不再對變數排他性存取。由於其它過程也可以訪問和改變變數的值,所以運營總值也許不可靠,代碼將更難於維護。
聲明所有的局部變數為靜態變數
為了使過程中所有的局部變數為靜態變數,可在過程頭的起始處加上 Static 關鍵字。例如:
Static Function RunningTotal (num)
這就使過程中的所有局部變數都變為靜態,無論它們是用 Static、Dim 或 Private 聲明的還是隱式聲明的。可以將 Static 放在任何 Sub 或 Funtion 過程頭的前面,包括事件過程和聲明為 Private 的過程。