靜態方法

了解用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數值。

觀察以下範例程式:

執行結果:

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

存取方式:

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

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

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

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

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

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

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

執行結果:

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

錯誤訊息第二行提到,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

Was this helpful?