C語言中文網 目錄
首頁 > Java教程 > Java類和對象 閱讀:1,192

Java static靜態修飾符詳解:靜態變量、靜態方法及靜態代碼塊

使用 static 修飾符修飾的屬性(成員變量)、常量和成員方法稱為靜態變量、常量和方法,它們統稱為靜態成員,歸整個類所有,不依賴于類的特定實例,被類的所有實例共享。只要這個類被加載,Java 虛擬機就可以根據類名在運行時數據區的方法區內找到它們。

調用靜態成員的語法形式如下:
類名.靜態成員

 靜態變量

實際上類的成員變量可以分為兩種:靜態變量(或稱為類變量),指被 static 修飾的成員變量;實例變量,指沒有被 static 修飾的成員變量。

靜態變量與實例變量的區別如下:
  • 對于靜態變量,運行時,Java 虛擬機只為靜態變量分配一次內存,在加載類的過程中完成靜態變量的內存分配。在類的內部,可以在任何方法內直接訪問靜態變量;在其他類中,可以通過類名訪問該類中的靜態變量。
  • 對于實例變量,每創建一個實例,Java 虛擬機就會為實例變量分配一次內存。在類的內部,可以在非靜態方法中直接訪問實例變量;在本類的靜態方法或其他類中則需要通過類的實例對象進行訪問。

靜態變量在類中的作用如下:
  • 靜態變量可以被類的所有實例共享,因此靜態變量可以作為實例之間的共享數據,增加實例之間的交互性。
  • 如果類的所有實例都包含一個相同的常量屬性,則可以把這個屬性定義為靜態常量類型,從而節省內存空間。例如,在類中定義一個靜態常量 PI。
public static double PI=3.14159256;

例 1

創建一個帶靜態變量的類,然后在 main() 方法中訪問該變量并輸出結果。
public class StaticVar
{
    public static String str1="Hello";
    public static void main(String[] args)
    {
        String str2="World!";
        //直接訪問str1
        String accessVar1=str1+str2;
        System.out.println("第 1 次訪問靜態變量,結果為:"+accessVar1);
        //通過類名訪問str1
        String accessVar2=StaticVar.str1+str2;
        System.out.println("第 2 次訪問靜態變量,結果為:"+accessVar2);
        //通過對象svt1訪問str1
        StaticVar svt1=new StaticVar();
        svt1.str1=svt1.str1+str2;
        String accessVar3=svt1.str1;
        System.out.println("第3次訪向靜態變量,結果為:"+accessVar3);
        //通過對象svt2訪問str1
        StaticVar svt2=new StaticVar();
        String accessVar4=svt2.str1+str2;
        System.out.println("第 4 次訪問靜態變量,結果為:"+accessVar4);
    }
}

運行該程序后的結果如下所示。
第 1 次訪問靜態變量,結果為:HelloWorld!
第 2 次訪問靜態變量,結果為:HelloWorld!
第 3 次訪向靜態變量,結果為:HelloWorld!
第 4 次訪問靜態變量,結果為:HelloWorld!World!

從運行結果可以看出,在類中定義靜態的屬性(成員變量),在 main() 方法中可以直接訪問,也可以通過類名訪問,還可以通過類的實例對象來訪問。

注意:靜態變量是被多個實例所共享的。

靜態方法

與成員變量類似,成員方法也可以分為兩種:靜態方法(或稱為類方法),指被 static 修飾的成員方法;實例方法,指沒有被 static 修飾的成員方法。

靜態方法與實例方法的區別如下:
  • 靜態方法不需要通過它所屬的類的任何實例就可以被調用,因此在靜態方法中不能使用 this 關鍵字,也不能直接訪問所屬類的實例變量和實例方法,但是可以直接訪問所屬類的靜態變量和靜態方法。另外,和 this 關鍵字一樣,super 關鍵字也與類的特定實例相關,所以在靜態方法中也不能使用 super 關鍵字。
  • 在實例方法中可以直接訪問所屬類的靜態變量、靜態方法、實例變量和實例方法。

例 2

創建一個帶靜態變量的類,添加幾個靜態方法對靜態變量的值進行修改,然后在 main() 方法中調用靜態方法并輸出結果。
public class StaticMethod
{
    public static int count=1;    //定義靜態變量count
    public int method1()
    {    //實例方法method1
        count++;    //訪問靜態變量count并賦值
        System.out.println("在靜態方法 method1()中的 count="+count);    //打印count
        return count;
    }
    public static int method2()
    {    //靜態方法method2
        count+=count;    //訪問靜態變量count并賦值
        System.out.println("在靜態方法 method2()中的 count="+count);    //打印count
        return count;
    }
    public static void PrintCount()
    {    //靜態方法PrintCount
        count+=2;
        System.out.println("在靜態方法 PrintCount()中的 count="+count);    //打印count
    }
    public static void main(String[] args)
    {
        StaticMethod sft=new StaticMethod();
        //通過實例對象調用實例方法
        System.out.println("method1() 方法返回值 intro1="+sft.method1());
        //直接調用靜態方法
        System.out.println("method2() 方法返回值 intro1="+method2());
        //通過類名調用靜態方法,打印coimt
        StaticMethod.PrintCount();
    }
}

運行該程序后的結果如下所示。
在靜態方法 method1()中的 count=2
method1() 方法返回值 intro1=2
在靜態方法 method2()中的 count=4
method2() 方法返回值 intro1=4
在靜態方法 PrintCount()中的 count=6

在該程序中,靜態變量 count 作為實例之間的共享數據,因此在不同的方法中調用 count,值是不一樣的。從該程序中可以看出,在靜態方法 method1() 和 PrintCount() 中是不可以調用非靜態方法 method1() 的,而在 method1() 方法中可以調用靜態方法 method2() 和 PrintCount()。

在訪問非靜態方法時,需要通過實例對象來訪問,而在訪冋靜態方法時,可以直接訪問,也可以通過類名來訪問,還可以通過實例化對象來訪問。

靜態代碼塊

靜態代碼塊指 Java 類中的 static{} 代碼塊,主要用于初始化類,為類的靜態變量賦初始值。靜態代碼塊的特點如下:
  • 靜態代碼塊類似于一個方法,但它不可以存在于任何方法體中。
  • Java 虛擬機在加載類時會執行靜態代碼塊,如果類中包含多個靜態代碼塊,則 Java 虛擬機將按它們在類中出現的順序依次執行它們,每個靜態代碼塊只會被執行一次。
  • 靜態代碼塊與靜態方法一樣,不能直接訪問類的實例變量和實例方法,而需要通過類的實例對象來訪問。

例 3

編寫一個 Java 類,在類中定義一個靜態變量,然后使用靜態代碼塊修改靜態變量的值。最后在 main() 方法中進行測試和輸出。
public class StaticCode
{
    public static int count=0;
    {
        count++;
        System.out.println("非靜態代碼塊 count="+count);
    }
    static
    {
        count++;
        System.out.println("靜態代碼塊 count="+count);
    }
    public static void main(String[] args)
    {
        System.out.println("*************** StaticCode1 執行 ***************");
        StaticCode sct1=new StaticCode();
        System.out.println("*************** StaticCode2 執行 ***************");
        StaticCode sct2=new StaticCode();
    }
}

如上述示例,為了說明靜態代碼塊只被執行一次,特地添加了非靜態代碼塊作為對比,并在主方法中創建了兩個類的實例對象。上述示例的執行結果為:
靜態代碼塊 count=1
*************** StaticCode1 執行 ***************
非靜態代碼塊 count=2
*************** StaticCode2 執行 ***************
非靜態代碼塊 count=3

精美而實用的網站,提供C語言C++STLLinuxShellJavaGo語言等教程,以及socketGCCviSwing設計模式JSP等專題。

Copyright ?2011-2018 biancheng.net, 陜ICP備15000209號

底部Logo