在物件導向程式設計中,類變量與實例變量的區別是基礎卻又容易被忽視的核心概念。許多開發者長期以為類變量只是「能透過類名直接訪問的靜態變量」,而實例變量則需「實例化後透過對象訪問」,卻忽略了最關鍵的區別:類變量在所有實例間共享同一份內存空間。
類變量(靜態變量)屬於類本身,在類加載時僅初始化一次。無論創建多少個實例,它們訪問的都是同一個記憶體地址。一個實例修改類變量,會立即影響所有其他實例。相反,實例變量屬於具體對象,每個實例擁有獨立的副本,互不干擾。
public class OO {
public static String classVar; // 類變量
public String instanceVar; // 實例變量
static { classVar = "Ever"; }
public static void main(String[] args) {
OO o1 = new OO();
OO o2 = new OO();
o1.instanceVar = "Once";
// 類變量地址相同
System.out.println(o1.classVar); // Ever
System.out.println(o2.classVar); // Ever
System.out.println(o1.classVar.hashCode() == o2.classVar.hashCode()); // true
o1.classVar = "123"; // 修改類變量
System.out.println(o2.classVar); // 123 (o2 受影響)
// 實例變量地址不同
System.out.println(o1.instanceVar.hashCode() == o2.instanceVar.hashCode()); // false (o2 為 null)
}
}
class C:
count = 0 # 類變量
def __init__(self):
self.num = 0 # 實例變量
def add(self):
C.count += 1 # 修改類變量
self.num += 1 # 修改實例變量
i1 = C()
i2 = C()
i1.add()
i2.add()
i2.add()
# 輸出結果:
# i1: count=3, num=1
# i2: count=3, num=2
# 類變量 count 為共享狀態,實例變量 num 獨立計數
理解這一機制,能有效避免「明明沒動這個對象,數據卻變了」的詭異 Bug,是進階開發者的必修課。