Java中的static介紹

來源:互聯網
上載者:User

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調用。。。
  


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.