ตัวแปรคลาส (Class Variables) และ Static Variables ใน Java
Class Variables เรียกอีกอย่างว่า Static Variables หรือ Fields ที่ประกาศด้วยคีย์เวิร์ด static อยู่ภายในคลาสแต่อยู่นอกเมธอด
คุณสมบัติหลัก
- เป็นของ Class ไม่ใช่ของ Instance (Object)
- มีเพียง หนึ่งสำเนา (Single copy) แชร์ให้ทุก Instance ใช้ร่วมกัน
- เข้าถึงได้โดย
ClassName.variableName(แนะนำ) หรือinstance.variableName(ทำงานได้แต่ไม่แนะนำ) - สร้างเมื่อโหลดคลาส (Class loading) ทำลายเมื่อ Unload คลาส
- ค่าเริ่มต้น (Default value) เหมือน Instance variables
ตัวอย่างโค้ดสมบูรณ์
public class Demo {
// Static variable (Class variable)
static int count = 0;
// Instance variable (เพื่อเปรียบเทียบ)
int instanceCount = 0;
public void increment() {
count++; // Static: แชร์ร่วมกัน
instanceCount++; // Instance: แยกต่างหาก
}
public static void main(String[] args) {
Demo obj1 = new Demo();
Demo obj2 = new Demo();
obj1.increment();
obj2.increment();
System.out.println("Static count (obj1): " + obj1.count); // 2
System.out.println("Static count (obj2): " + obj2.count); // 2 (ค่าเดียวกัน!)
System.out.println("Static count (Demo.count): " + Demo.count); // 2 (เข้าถึงผ่านคลาส)
System.out.println("Instance count (obj1): " + obj1.instanceCount); // 1
System.out.println("Instance count (obj2): " + obj2.instanceCount); // 1 (ต่างกัน!)
}
}
ผลลัพธ์
Static count (obj1): 2
Static count (obj2): 2
Static count (Demo.count): 2
Instance count (obj1): 1
Instance count (obj2): 1
Static Constants (ค่าคงที่)
public class Constants {
// Convention: UPPER_SNAKE_CASE
public static final double PI = 3.14159265359;
public static final int MAX_USERS = 100;
public static final String APP_NAME = "MyApp";
// Compile-time constant (ใน bytecode จะแทนค่าตรงๆ)
public static final int COMPILE_TIME_CONST = 42;
}
Static Initialization Block
public class DatabaseConfig {
static String url;
static String username;
static String password;
// Static block: รันครั้งเดียวตอนโหลดคลาส
static {
try {
// โหลดจาก config file, environment variables ฯลฯ
url = "jdbc:mysql://localhost:3306/mydb";
username = System.getenv("DB_USER");
password = System.getenv("DB_PASS");
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
}
Static Methods
- เข้าถึงได้เฉพาะ static members (variables/methods)
- ไม่สามารถใช้
thisหรือsuperได้ - ไม่สามารถ Override ได้ (แต่สามารถ Hide ได้)
- Utility classes มักเป็น static methods ทั้งหมด
การเปรียบเทียบ Static vs Instance
| คุณสมบัติ | Static Variable | Instance Variable |
|---|---|---|
| ความเป็นเจ้าของ | Class | Object (Instance) |
| จำนวนสำเนา | 1 ต่อ Class | 1 ต่อ Object |
| อายุชีวิต | Class loaded → JVM exit | Object created → GC |
| การเข้าถึง | ClassName.var / obj.var | obj.var เท่านั้น |
| Thread Safety | ต้อง synchronized เอง | แยกกันแล้ว (แต่ shared object ต้องระวัง) |
แนวทางปฏิบัติที่ดี
- ใช้
static finalสำหรับ Constants - หลีกเลี่ยง Mutable Static State (ยากต่อการ Test และ Thread Safety)
- ใช้ Singleton Pattern แทน Static variables สำหรับ State ที่ซับซ้อน
- เข้าถึงผ่าน ClassName เสมอ (ClassName.staticVar) เพื่อความชัดเจน
- Static imports สำหรับ static methods/constants ที่ใช้บ่อย:
import static java.lang.Math.*;