靜態(tài)變量與非靜態(tài)變量的區(qū)別
靜態(tài)變量:靜態(tài)變量使用 static 修飾符進(jìn)行聲明在所屬類被裝載時(shí)創(chuàng)建通過類進(jìn)行訪問所屬類的所有實(shí)例的同一靜態(tài)變量都是同一個(gè)值非靜態(tài)變量:不帶有 static 修飾符聲明的變量稱做非靜態(tài)變量在類被實(shí)例化時(shí)創(chuàng)建通過對(duì)象進(jìn)行訪問同一個(gè)類的不同實(shí)例的同一非靜態(tài)變量可以是不同的值。
對(duì)于自動(dòng)變量,它屬于動(dòng)態(tài)存儲(chǔ)方式。但是也可以用static定義它為靜態(tài)自動(dòng)變量,或稱靜態(tài)局部變量,從而成為靜態(tài)存儲(chǔ)方式。由此看來,一個(gè)變量可由static進(jìn)行再說明,并改變其原有的存儲(chǔ)方式。
下面介紹靜態(tài)變量與非靜態(tài)變量的區(qū)別如下:
1.內(nèi)存分配
靜態(tài)變量在應(yīng)用程序初始化時(shí),就存在于內(nèi)存當(dāng)中,直到它所在的類的程序運(yùn)行結(jié)束時(shí)才消亡;而非靜態(tài)變量需要被實(shí)例化后才會(huì)分配內(nèi)存。
2.生存周期
靜態(tài)變量生存周期為應(yīng)用程序的存在周期;非靜態(tài)變量的存在周期取決于實(shí)例化的類的存在周期。
3.調(diào)用方式
靜態(tài)變量只能通過“類.靜態(tài)變量名”調(diào)用,類的實(shí)例不能調(diào)用;非靜態(tài)變量當(dāng)該變量所在的類被實(shí)例化后,可通過實(shí)例化的類名直接訪問。
4.共享方式
靜態(tài)變量是全局變量,被所有類的實(shí)例對(duì)象共享,即一個(gè)實(shí)例的改變了靜態(tài)變量的值,其他同類的實(shí)例讀到的就是變化后的值;
非靜態(tài)變量是局部變量,不共享的。
5.訪問方式
靜態(tài)成員不能訪問非靜態(tài)成員;非靜態(tài)成員可以訪問靜態(tài)成員。
靜態(tài)變量在類裝載的時(shí)候分配內(nèi)存,以后創(chuàng)建的對(duì)象都使用的該內(nèi)存,相應(yīng)的操作也就是對(duì)這塊內(nèi)存進(jìn)行操作。也可以看作是另類的全局變量。
在WebSerivice中想只進(jìn)行一次初始化,而不用每次都進(jìn)行初始化這樣占用大量資源。還可以對(duì)調(diào)用的服務(wù)進(jìn)行管理,比如想把每次調(diào)用的服務(wù)進(jìn)行排隊(duì)執(zhí)行,可以將想應(yīng)信息放到Arraylist中,靜態(tài)時(shí)鐘中排隊(duì)執(zhí)行。
C#靜態(tài)構(gòu)造函數(shù)及靜態(tài)變量
靜態(tài)構(gòu)造函數(shù):
(1)用于對(duì)靜態(tài)字段、只讀字段等的初始化。
(2)添加static關(guān)鍵字,不能添加訪問修飾符,因?yàn)殪o態(tài)構(gòu)造函數(shù)都是私有的。
(3)類的靜態(tài)構(gòu)造函數(shù)在給定應(yīng)用程序域中至多執(zhí)行一次:只有創(chuàng)建類的實(shí)例或者引用類的任何靜態(tài)成員才激發(fā)靜態(tài)構(gòu)造函數(shù)
(4)靜態(tài)構(gòu)造函數(shù)是不可繼承的,而且不能被直接調(diào)用。
(5)如果類中包含用來開始執(zhí)行的 Main 方法,則該類的靜態(tài)構(gòu)造函數(shù)將在調(diào)用 Main 方法之前執(zhí)行。
(6)任何帶有初始值設(shè)定項(xiàng)的靜態(tài)字段,則在執(zhí)行該類的靜態(tài)構(gòu)造函數(shù)時(shí),先要按照文本順序執(zhí)行那些初始值設(shè)定項(xiàng)。
(7)如果沒有編寫靜態(tài)構(gòu)造函數(shù),而這時(shí)類中包含帶有初始值設(shè)定的靜態(tài)字段,那么編譯器會(huì)自動(dòng)生成默認(rèn)的靜態(tài)構(gòu)造函數(shù)。
經(jīng)典例子:
- /*
- * 靜 態(tài) 構(gòu) 造 函 數(shù) 練 習(xí)
- * (1)①②③……為執(zhí)行順序
- * (2)輸出結(jié)果: static A()
- * static B()
- * X = 1, Y = 2
- */
- using System;
- class A
- {
- public static int X;
- static A() //④ 執(zhí)行完后返回到③
- {
- X = B.Y + 1;
- Console.WriteLine("static A()");
- }
- }
- class B
- {
- public static int Y = A.X + 1; //③ 調(diào)用了A的靜態(tài)成員,
- // 轉(zhuǎn)到A的靜態(tài)構(gòu)造函數(shù)---->
- static B() //② 如果帶有初始值設(shè)定項(xiàng)的靜態(tài)字段,
- // 執(zhí)行該類的靜態(tài)構(gòu)造函數(shù)時(shí),
- // 先要按照文本順序執(zhí)行那些初始值設(shè)定項(xiàng)。
- // 轉(zhuǎn)到初始值設(shè)定項(xiàng)---->
- {
- Console.WriteLine("static B()");
- }
- static void Main() //① 程序入口,
- // 如果類中包含用來開始執(zhí)行的 Main 方法,
- // 該類的靜態(tài)構(gòu)造函數(shù)將在調(diào)用 Main 方法之前執(zhí)行。
- // 轉(zhuǎn)到B的靜態(tài)構(gòu)造函數(shù)---->
- {
- Console.WriteLine("X = {0}, Y = {1}", A.X, B.Y);//⑤ 輸出結(jié)果
- Console.ReadLine();
- }
- }
關(guān)于C#靜態(tài)構(gòu)造函數(shù)的幾點(diǎn)說明:
靜態(tài)構(gòu)造函數(shù)是C#的一個(gè)新特性,其實(shí)好像很少用到。不過當(dāng)我們想初始化一些靜態(tài)變量的時(shí)候就需要用到它了。這個(gè)構(gòu)造函數(shù)是屬于類的,而不是屬于哪里實(shí)例的,就是說這個(gè)構(gòu)造函數(shù)只會(huì)被執(zhí)行一次。也就是在創(chuàng)建***個(gè)實(shí)例或引用任何靜態(tài)成員之前,由.NET自動(dòng)調(diào)用。
- class SimpleClass
- {
- // Static constructor
- static SimpleClass()
- {
- //
- }
- }
在使用靜態(tài)構(gòu)造函數(shù)的時(shí)候應(yīng)該注意幾點(diǎn):
1、靜態(tài)構(gòu)造函數(shù)既沒有訪問修飾符,也沒有參數(shù)。因?yàn)槭?NET調(diào)用的,所以像public和private等修飾符就沒有意義了。
2、是在創(chuàng)建***個(gè)類實(shí)例或任何靜態(tài)成員被引用時(shí),.NET將自動(dòng)調(diào)用靜態(tài)構(gòu)造函數(shù)來初始化類,也就是說我們無法直接調(diào)用靜態(tài)構(gòu)造函數(shù),也就無法控制什么時(shí)候執(zhí)行靜態(tài)構(gòu)造函數(shù)了。
3、一個(gè)類只能有一個(gè)靜態(tài)構(gòu)造函數(shù)。
4、無參數(shù)的構(gòu)造函數(shù)可以與靜態(tài)構(gòu)造函數(shù)共存。盡管參數(shù)列表相同,但一個(gè)屬于類,一個(gè)屬于實(shí)例,所以不會(huì)沖突。
5、最多只運(yùn)行一次。
6、靜態(tài)構(gòu)造函數(shù)不可以被繼承。
7、如果沒有寫靜態(tài)構(gòu)造函數(shù),而類中包含帶有初始值設(shè)定的靜態(tài)成員,那么編譯器會(huì)自動(dòng)生成默認(rèn)的靜態(tài)構(gòu)造函數(shù)。
希望通過閱讀本文,能給你帶來幫助。
【編輯推薦】