靜態方法

了解用static修飾方法時要注意的地方及限制。

現在我們知道關鍵字static 是用來讓成員從『一般物件成員』變成『類別成員』,上一篇說明了類別變數的使用,這裡要談的是修飾方法(method)。

再次拿出Human類別來討論:

class Human{
  static int total = 0;
  String name;
  int age;
  int height;
  Human(String str){
      name = str;
      total++;
  }// end of constructor(String)
  void printName(){
      System.out.println("姓名:"+name);
  }// end of printName();
  static void printTotal(){
      System.out.println("總人數:"+total);
  }// end of printTotal();
}// end of class Human

這次重點放在這兩個方法上:printName()印出該物件的name欄位、printTotal()以static修飾,印出目前Human的total數值。

觀察以下範例程式:

class Test{
  public static void main(String[] args){
      Human.printTotal();
      Human tina = new Human("小婷");
      tina.printName();
      Human yubin = new Human("小木");
      yubin.printName();
      Human.printTotal();
  }// end of main(String[])
}// end of class Test

執行結果:

總人數:0
姓名:小婷
姓名:小木
總人數:2

嗯,看起來很合邏輯。類別方法印出類別的成員,物件方法印出物件成員。 這樣寫是絕對直覺且正確。

存取方式:

類別名稱 . 靜態方法 ;

靜態方法屬於類別所以用類別名稱去存取。

另外我們知道,一般物件也可以存取到類別成員。

若將上述printName()方法改寫成這樣:

void printName(){
    // 除了存取一般變數name,還多了存取靜態變數total
    System.out.println("姓名:"+name+",總人數:"+total); 
}// end of printName()

一樣執行上述範例程式,輸出結果:

總人數:0
姓名:小婷,總人數:1
姓名:小木,總人數:2
總人數:2

物件可以存取到類別變數,當然物件方法也可以存取類別變數。

但若是類別方法要存取物件成員呢?

試著將printName()方法以static 修飾,讓它變成類別方法。

static void printName(){
    System.out.println("姓名:"+name);
}// end of printName();

執行結果:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
Cannot make a static reference to the non-static field name

at Test$Human.printName
at Test.main

嗯,當然這不是正確的輸出結果。這是『編譯錯誤』的訊息。

錯誤訊息第二行提到,Cannot make a static reference to the non-static field name. 指的就是static的方法不能存取到non-static的欄位。

於是乎我們可以輕鬆得到一個結論

物件方法,可以存取物件成員及類別成員。 Object method can access non-static field or static field.

類別方法,只能存取類別成員。Static method can only access static field.

但是為什麼?

程式設計師把資料存入記憶體來做運算,因此可以讀取的資料限定『已經存在記憶體中』,嗯,不然根本沒資料是要存取什麼?

還記得第一篇講的static跟non-static的差異嗎?就是載入記憶體的時機。程式剛載入還沒執行的時候,static的方法已經載入記憶體且隨時可以被呼叫,但這個時候一般變數的成員(non-static)還沒被初始化,還沒在記憶體中佔有空間,直白一點說就是根本還不存在。

所以static的方法在程式裡面限定只能存取static的欄位,因為一定要確保存取的到東西嘛。

Last updated