Static variable and Static methods
- 總是用同樣的方式執行method: 想像一個情境,當有一個Time的Class內有一個display method,裡面的唯一功能就是印出今天的時間,也就是說不管今天Time的instance狀態為何,都不會改變display method輸出的結果。既然這個method不會和instance的狀態有任何關係,其實也不需要透過instance執行它。那麼其實就可以透過class來執行它!
- 紀錄instance個數: 假設今天我們想要知道一個Class有多少個instance個數,這時候不能把這個變數當成instance variable,因為一旦new了一個instance,這個值就會歸0
- 被標示成static的variable或是method是屬於class的,並不是屬於instance的
- 可以不透過instance去存取,僅透過class就能存取static的variable或是method
- instance間共享static class和一份static variable
下面的例子示範static variable
下面的例子示範static variable
public class Language { static int counter; public Language(){ counter++; } public static void main(String[] args){ new Language(); new Language(); new Language(); System.out.println(counter); } }
- static variable不需要初始化,在class被JVM第一次載入的時候就會給初始值了。
- 不論何時new instance,都會靜態的增加counter的值。而這個程式跑完的結果是"3"
如果將static variable改成instance variable
public class Language { int counter; public Language(){ counter++; } public static void main(String[] args){ new Language(); new Language(); new Language(); System.out.println(counter); } }
常見錯誤範例: 在static method裡面對instance variable做存取
public class Display { int x = 3; public static void main(String[] args){ System.out.println(x);//Compile error! } }
對static method而言,根本不知道這個存取的instance variable是指哪個instance內的variable。因為static method是class等級來執行的。規則是:一個class的static method,不能存取它自己type的instance variable or method。
Access static variable and static methods
要使用static variable,可以使用class+"."+static variable,例如Language.counter
但是,Java也允許以下用法:
public class Language { static int counter; public Language(){ counter++; } public static void main(String[] args){ Language l = new Language(); System.out.println(l.counter); } }
也就是可以使用new出來object的reference variable去存取static variable。但在這邊要注意
- 對JVM來說,他看到的其實是Language.counter,就算寫的是l.counter(也就是class等級)。
- 雖然使用reference variable對static variable做存取,但是static members還是不知道是誰對他們做了存取,只知道是type是Language。換句話說,compiler只關心type是誰。
注意!static method是不能被override,就算真的在subclass寫了一個一樣的static method,那也只是從新定義一個新的static method而已,並不是override。如下範例:
class Animal{ static void display(){ System.out.println("Use Animal static method"); } } class Cat extends Animal{ static void display(){ System.out.println("Use Cat static method"); } } class testOverrideStatic { public static void main(String[] args){ Animal[] animalArray = {new Animal(), new Cat(), new Animal()}; for(Animal a:animalArray){ a.display(); } } }
Use Animal static method Use Animal static method Use Animal static method
- 此行a.display()對compiler來說會自動轉成Animal.display()
- 就算有Cat()的物件在執行a.display(),對編譯器來說只參考reference variable的type是誰(此處皆是Animal)
Static method不能被override的原因:
想想為什麼要override,原因是透過polymorphism來實現該實體透過override去執行真正需要做的事情。既然static不在class層,不需要instance就能夠執行,代表也不需要有override的行為(因為沒辦法使用instance透過polymorphism找出真正被實作的method)
另外static method的好處:不需要等到runtime的時候才決定要做的真實method是哪一個,可以加快速度。
沒有留言:
張貼留言