static修飾的成員變數:static修飾的成員變數也叫類變數或全域變數,在類被載入時static修飾的成員變數被初始化,與類關聯,只要類存在,static變數就存在。
一個static變數單獨劃分一Block Storage空間,不與具體的對象綁定在一起,該儲存空
間被類的各個對象所共用。也就是說當聲明一個對象時,並不產生static變數的拷貝,而是該類所有的執行個體對象共用同一個static變數。static
修飾的成員變數能在建立任何執行個體對象之前被訪問,而不必引用任何對象,也就是說不管建立多少對象,static修飾的變數只佔有一塊記憶體。
Static :對於類的屬性來說
有類變數和執行個體變數
class StaticTest
{ static int i=47;
}
對於不同的對象 StaticTest st1=new StaticTest();StaticTest st2=new StaticTest()都
只有一個共用的儲存空間!
引用Static變數有兩種方法.可以用一個對象去定位他。.也可以用其類名直接調用!(最好通過類名,這樣不至於讓看程式的人感到疑惑)
如果一個成員被聲明為
static
,他就能夠在他的類的對象被建立之前被訪問,
不必引用任何對象。最常見的例子是
main()
方法,
static
定義的變數會優先於任何其它非
static
變數,不論其出現的順序如何;
Java變數在類這個層級分兩種,類變數(static)和執行個體變數,
而在靜態方法中不能夠直接存取執行個體變數,執行個體變數需要初始化一個類的執行個體才可以用。
靜態東西之所以有這種區分是為了區別對待類和對象的成員。
如果某個變數或者方法被聲明為static,意味著在類初始化時就必須分配記憶體空間。
而方法調用內部需要的變數既然是臨時的,會隨著方法調用結束而失效的
,那麼沒有道理讓它成為static的對吧
1.靜態變數屬於類,為該類所有對象所分享,在程式開始執行前就分配記憶體空間,
其作用可以類似VB中的全域變數
,如果前面加上final,功能類似全域常量,不可以修改其值.比如圓周率
2.類的靜態方法
不能訪問類的執行個體變數,
可以訪問類的靜態變數、執行個體化的類的執行個體變數
3
.靜態方法中不能定義靜態變數的
我和作者一樣,推薦下面的代碼:
public class ExplicitStatic{
public static void main(String[] args){
System.out.println("Inside main()");
Cups.c1.f(99);
}
static Cups x=new Cups();
static Cups y=new Cups();
}
class Cup{
Cup(int marker){
System.out.println("Cup("+marker+")");
}
void f(int marker){
System.out.println("f("+marker+")");
}
}
class Cups{
static Cup c1=new Cup(11);
static Cup c2;
Cup c3=new Cup(33);
Cup c4;
{ c3=new Cup(3);
c4=new Cup(4);
}
static{
c1=new Cup(1);
c2=new Cup(2);
}
Cups(){
System.out.println("Cups()");
}
}
/*輸出結果:
cup(11)
cup(1)
cup(2)
cup(33)
cup(3)
cup(4)
cups()
cup(33)
cup(3)
cup(4)
cup()
inside main()
f(99)
*/
/*
首先初始化的是static,順序是代碼順序up-to-down!然後在是自己調用的方法!
上面的執行順序是
1: static Cups x=new Cups(); 轉入 Cups對象
2: static Cup c1=new Cup(11); 轉入 Cup對象
3: 執行Cup的輸出 Cup(11);
4: cups對象裡的 static Cup c2;
5: static{
c1=new Cup(1);轉入Cup對象 輸出 Cup(1)
c2=new Cup(2);轉入Cup對象 輸出 Cup(2)
}
6: cups對象裡的 Cup c3=new Cup(33); 輸出 Cup(33)
7:c3=new Cup(3); 輸出 Cup(3)
c4=new Cup(4); 輸出 Cup(4)
8:Cups(){
System.out.println("Cups()"); 輸出 Cups()
}
9:static Cups y=new Cups();
注意Cups裡的static成員已經初始化 所以 static Cup c1=new Cup(11);
static Cup c2;static{
c1=new Cup(1);
c2=new Cup(2);
}
不在執行!
下面的就和上面一樣了!
*/
首次使用的地方也是static初始化發生的地方。裝載的時候,所有static對象和static代碼塊都會按照本來的順序初始化(亦即它們在類定義代碼裡寫入的順序)。
當然,static資料只會初始化一次。
程式一開始訪問MAIN方法,然後開始一載入對應的CLASS檔案,如果他具有基類,載入基類,最後完成STATIC的初始化。
-----------------------------------------------------------------------------------------------------------------------------------
《
建議:慎用static變數
》
(轉自論壇)
這兩天我們舉行了一個有關人力資源系統的培訓班,發現一個表象問題:session的值亂串,起初一直以為是session的問題,但是通過跟蹤,資料值完全正確,沒有一絲的異常;最後通過作業的交替執行,發現session確實發生變化,通過代碼尋找,發現其中某個值在傳入前是static的;
所以呢,對static變數,當a寫入session後,還沒有繼續作業,b又重新寫入session並作業完成,而後a繼續作業,此時a擷取的session值已經不是原來的值了。
(回複)
static 實際上是用地址的,所以會有這樣的問題。
如果需要 可以 採用singleton模式(單例模式)。
java 裡面本身就要慎用static變數。
變數的範圍範圍沒有搞清楚,肯定會出問題的。在分析自己自己的目的後,用Static還是很有效果的。比如在Servlet查DB得到公司的地址本(因為是不變的),儲存到Static變數裡,就只與DB互動一次:)。
如果不是公用變數,那就別使用static。
-----------------------------------------------------------------------------------------------------------------------------------
static塊
VAR1和VAR2定義成final,值存在一個properties檔案中,在使用前必須將值load進來:
System.getProperties().load(new FileInputStream("constants.properties"));
將代碼放在static塊中:
punlic final class Constants{
static{
System.getProperties().load(new FileInputStream("constants.properties"));
}
public static final int VAR2 = System.getProperties().getProperty("var2");
public static final int VAR1 = System.getProperties().getProperty("var1");
}
但在運行時VAR1和VAR2沒有被賦值,debug後發現static塊根本沒有執行。
於是頓悟:final變數在編譯時間便被編譯期計算、賦值,因此在運行時沒有必要執行static塊。
-----------------------------------------------------------------------------------------------------------------------------------
Java語言可以使用static關鍵字修飾類的成員變數和成員方法。被static修飾的成員變數,成員方法一般被稱為靜態(或者全域)變數(static field),靜態方法(static method)。
有別於一般的變數和方法,靜態變數,靜態方法的範圍是類的所有對象。也就是說,當運行時,在程式空間中,類的所有對象訪問到的靜態變數都是同一個值,當其中一個對象改變了靜態變數的值,其他對象都將受到影響。
正因為這樣,靜態變數,靜態方法可以(建議)通過 類名.靜態變數/類名.靜態方法
直接存取。
對象.變數/方法:
沒有使用static修飾的成員變數,成員方法是作用於對象域的,通常被稱作物件變數(instance
field),對象方法(instance
method)。當某個對象被建立時,它們才真正地存在於記憶體空間之中,而且對象本身對它們的改變,不會影響到其它對象。就好像
Person的一個對象zhangsan,zhangsan的改變不會影響到其它Person對象一樣。
類.變數/方法:
使用static修飾的成員變數,成員方法可以看作類的固有的,它作用於類的全體對象。
當類的所有對象需要共用同一值時,可以使用static來定義。
例如,一個店鋪(類),擁有多個分店(對象),便可以使用一個static變數來描述所有店的總營業額,這樣每一個分店可以簡單地訪問(讀/寫)到公用的店的總營業額。
又如,PI=3.1415926,這時可以使用static來定義PI變數。當然,通常這種不希望改變static變數的情況,一般使用static final來修飾。
-----------------------------------------------------------------------------------------------------------------------------------
1、如果需要通過計算來初始化你的static變數,你可以聲明一個static塊,Static 塊僅在該類被載入時執行一次。
2、
聲明為static的變數實質上就是全域變數。
當聲明一個對象時,並不產生static變數的拷貝,而是該類所有的執行個體變數共用同一個static變數。
聲明為static的方法有以下幾條限制:
◆它們僅能調用其他的static 方法。
◆它們只能訪問static資料。
◆它們不能以任何方式引用this 或super
3、聲明為static的變數在定義的地方被初始化,並且只能初始化一次。
也就是說如果你在一個方法裡定義了一個static變數,當你第二次調用該方法時,該變數不被再次初始化。
4、聲明為static的話就只佔用一份記憶體空間,不會改變
。
而且只是在class被裝載的時候被初始化一次
。
可以由所屬的class調用。。。