Java static 關鍵字
static 表示屬於類別而非物件,所有實例共享。
靜態變數
public class Counter {
private static int count = 0; // 靜態變數,所有物件共享
private int id; // 實例變數,每個物件各自擁有
public Counter() {
count++;
this.id = count;
}
public static int getCount() {
return count;
}
public int getId() {
return id;
}
}
Counter c1 = new Counter(); // count=1, id=1
Counter c2 = new Counter(); // count=2, id=2
Counter c3 = new Counter(); // count=3, id=3
System.out.println(Counter.getCount()); // 3
靜態方法
靜態方法屬於類別,可以直接用類別名稱呼叫:
public class MathUtils {
public static int add(int a, int b) {
return a + b;
}
public static int max(int a, int b) {
return (a > b) ? a : b;
}
}
// 使用類別名稱呼叫
int sum = MathUtils.add(5, 3); // 8
int max = MathUtils.max(10, 20); // 20
靜態方法的限制
靜態方法不能存取實例變數和實例方法:
public class Example {
private int value = 10; // 實例變數
private static int count = 0; // 靜態變數
public static void staticMethod() {
// System.out.println(value); // 錯誤!
System.out.println(count); // OK
// instanceMethod(); // 錯誤!
anotherStatic(); // OK
}
public void instanceMethod() {
System.out.println(value); // OK
System.out.println(count); // OK(可以存取靜態)
}
public static void anotherStatic() {
// ...
}
}
靜態常數
public class Constants {
public static final double PI = 3.14159;
public static final int MAX_SIZE = 100;
public static final String APP_NAME = "MyApp";
}
// 使用
double area = Constants.PI * radius * radius;
靜態區塊
用於初始化靜態變數:
public class DatabaseConfig {
private static String url;
private static String username;
// 靜態區塊,類別載入時執行一次
static {
System.out.println("載入設定...");
url = "jdbc:mysql://localhost:3306/db";
username = "admin";
}
public static String getUrl() {
return url;
}
}
靜態內部類別
public class Outer {
private static int outerStatic = 10;
private int outerInstance = 20;
// 靜態內部類別
public static class Inner {
public void print() {
System.out.println(outerStatic); // OK
// System.out.println(outerInstance); // 錯誤!
}
}
}
// 使用
Outer.Inner inner = new Outer.Inner();
inner.print();
靜態 import
可以直接使用靜態成員而不需要類別名稱:
import static java.lang.Math.PI;
import static java.lang.Math.sqrt;
public class Circle {
public double getArea(double radius) {
return PI * radius * radius; // 不需要 Math.PI
}
public double getDiagonal(double a, double b) {
return sqrt(a * a + b * b); // 不需要 Math.sqrt
}
}
實際應用
工具類別
public class StringUtils {
private StringUtils() {} // 私有建構子
public static boolean isEmpty(String s) {
return s == null || s.isEmpty();
}
public static String capitalize(String s) {
if (isEmpty(s)) return s;
return Character.toUpperCase(s.charAt(0)) + s.substring(1);
}
}
單例模式
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
計數器
public class User {
private static int totalUsers = 0;
private int userId;
private String name;
public User(String name) {
totalUsers++;
this.userId = totalUsers;
this.name = name;
}
public static int getTotalUsers() {
return totalUsers;
}
}
靜態 vs 實例
| 特性 | 靜態 | 實例 |
|---|---|---|
| 屬於 | 類別 | 物件 |
| 記憶體 | 一份 | 每個物件一份 |
| 存取方式 | 類別.成員 | 物件.成員 |
| 使用 this | 不可以 | 可以 |
| 存取實例成員 | 不可以 | 可以 |
何時使用 static
- 工具方法(不需要物件狀態)
- 常數
- 工廠方法
- 計數器或共享資料
- main 方法