Java 學習記錄59 — static

張小雄
11 min readApr 26, 2021

--

今天要學的是 static

StaticTest.java

public class StaticTest {
private int numInstances = 0;
private String name;
public StaticTest(String name) {
this.name = name;
numInstances++;
}
public int getNumInstances() {
return numInstances;
}
public String getName() {
return name;
}
}

MainStaticTest.java

public class MainStaticTest {
public static void main(String[] args) {
StaticTest firstInstance = new StaticTest("1st instance");
System.out.println(firstInstance.getName() + " is instance number " + firstInstance.getNumInstances());
StaticTest secondInstance = new StaticTest("2nd instance");
System.out.println(secondInstance.getName() + " is instance number " + secondInstance.getNumInstances());
}
}

輸出結果:

1st instance is instance number 1

2nd instance is instance number 1

簡單的計數功能

StaticTest.java 改

public  class StaticTest {
private static int numInstances = 0;
private String name;
public StaticTest(String name) {
this.name = name;
numInstances++;
}
public int getNumInstances() {
return numInstances;
}
public String getName() {
return name;
}
}

MainStaticTest.java 改

public class MainStaticTest {
public static void main(String[] args) {
StaticTest firstInstance = new StaticTest("1st instance");
System.out.println(firstInstance.getName() + " is instance number " + firstInstance.getNumInstances());
StaticTest secondInstance = new StaticTest("2nd instance");
System.out.println(secondInstance.getName() + " is instance number " + firstInstance.getNumInstances());
StaticTest thirdInstance = new StaticTest("3rd instance");
System.out.println(thirdInstance.getName() + " is instance number " + thirdInstance.getNumInstances());
}
}

輸出結果:

1st instance is instance number 1

2nd instance is instance number 2

3rd instance is instance number 3

就只是把 numInstances 加上 static

可是輸出結果變得不一樣了

在 secondInstance 的輸出是寫 firstInstance.getNumInstances()

數字竟然不是顯示 1 還是增加變成 2

下一行 thirdInstance 輸出就正常寫自己

但數字也是增加了 1 繼續變成 3

這是因為改成 static 後

裡面的 fileds 就不是跟著 instance of class 走

而是跟著 class 本身走

StaticTest.java 改

public  class StaticTest {
private static int numInstances = 0;
private String name;
public StaticTest(String name) {
this.name = name;
numInstances++;
}
public static int getNumInstances() {
return numInstances;
}
public String getName() {
return name;
}
}

MainStaticTest.java 改

public class MainStaticTest {
public static void main(String[] args) {
StaticTest firstInstance = new StaticTest("1st instance");
System.out.println(firstInstance.getName() + " is instance number " + StaticTest.getNumInstances());
StaticTest secondInstance = new StaticTest("2nd instance");
System.out.println(secondInstance.getName() + " is instance number " + StaticTest.getNumInstances());
StaticTest thirdInstance = new StaticTest("3rd instance");
System.out.println(thirdInstance.getName() + " is instance number " + StaticTest.getNumInstances());
}
}

輸出結果:

1st instance is instance number 1

2nd instance is instance number 2

3rd instance is instance number 3

這次把 getNumInstances() 也加上 static

輸出也改成了 StaticTest.getNumInstances()

如果用 static 不要用 instance of class 去調用會比較合理

簡單的說 沒有寫 static 就是用 instance of class 去調用,各個 instance of class 中保存的資料,是屬於各自的,互相獨立互不干擾

若寫上 static 就不需要使用 instance of class 去調用,可直接使用 class,資料也只會跟著 class 走,這時如果用 inatance of class 去調用還是共同享有一份 class 裡的資料

MainStaticTest.java 改

public class MainStaticTest {    public int multiplier = 7;    public static void main(String[] args) {
StaticTest firstInstance = new StaticTest("1st instance");
System.out.println(firstInstance.getName() + " is instance number " + StaticTest.getNumInstances());
StaticTest secondInstance = new StaticTest("2nd instance");
System.out.println(secondInstance.getName() + " is instance number " + StaticTest.getNumInstances());
StaticTest thirdInstance = new StaticTest("3rd instance");
System.out.println(thirdInstance.getName() + " is instance number " + StaticTest.getNumInstances());
int answer = multiply(5);
System.out.println("The answer is " + answer);
System.out.println("Multiplier is " + multiplier);
} public int multiply(int number) {
return number * multiplier;
}
}

在上方增加了 field 跟下方增加了 method

結果在 main 裡調用時,皆被提示錯誤

Tim 有說到 mian 之所以是 static

原因是程序啟動的時候,並還沒有任何 instance of class

那麼需要從 instance of class 調用的任何東西根本全部都無法使用

所以才需要有 static 的誕生

這樣從 cmd 操作程序的時候才有東西能執行

例如:java 路徑名.檔案名.Main

回到範例

那麼 main 已經是 static,那麼不是 static 的東西當然不能直接在這個區塊裡被使用

要使用不是static 就要用 instance of class 才能被使用

也就是說 static main 裡面只有兩種東西能被使用

要麻已經是 instance of class,例如:StaticTest firstInstance = new StaticTest("1st instance");

然後用 firstInstance.OOO 去調用各種資源

要麻是 static 可以直接用 className.OOO 去做調用

所以改成這樣即可

public class MainStaticTest {    public static int multiplier = 7;    public static void main(String[] args) {
StaticTest firstInstance = new StaticTest("1st instance");
System.out.println(firstInstance.getName() + " is instance number " + StaticTest.getNumInstances());
StaticTest secondInstance = new StaticTest("2nd instance");
System.out.println(secondInstance.getName() + " is instance number " + StaticTest.getNumInstances());
StaticTest thirdInstance = new StaticTest("3rd instance");
System.out.println(thirdInstance.getName() + " is instance number " + StaticTest.getNumInstances());
int answer = multiply(5);
System.out.println("The answer is " + answer);
System.out.println("Multiplier is " + multiplier);
} public static int multiply(int number) {
return number * multiplier;
}
}

簡單的總結就是

如果不想要使用 instance of class 去調用資料,就在該 method 或 field 的前綴加入 static 即可

就可以直接使用 className.filed or className.method 來做調用

但要注意裡面的數據就是共用的了,而不是各自擁有獨立的數據

且標記成 statc 後哪怕你後面改用 instance 去調用

數據照樣是共用的,而不是各個 instance of class 後出現的 object 擁有各自獨立數據

所以才會建議要用 className 去調用,才不會混淆其他使用者或未來觀看的自己

--

--

張小雄
張小雄

Written by 張小雄

記錄成為軟體工程師的過程

No responses yet