# 靜態方法

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

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

再次拿出Human類別來討論：

```java
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數值。

觀察以下範例程式：

```java
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
```

執行結果：

```java
總人數：0
姓名：小婷
姓名：小木
總人數：2
```

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

## 存取方式：

```java
類別名稱 . 靜態方法 ;
```

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

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

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

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

一樣執行上述範例程式，輸出結果：

```java
總人數：0
姓名：小婷，總人數：1
姓名：小木，總人數：2
總人數：2
```

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

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

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

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

執行結果：

```java
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的欄位，因為一定要確保存取的到東西嘛。
