Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Java

Biến lớp (Class Variables) và Static Variables trong Java

Class variable (biến lớp) còn gọi là static variable (biến tĩnh) – được khai báo với từ khóa static bên trong class nhưng ngoài mọi method/constructor/block.

Đặc điểm chính

  • Thuộc về class, không thuộc về instance (object) nào.
  • Chỉ có một bản sao (single copy) được chia sẻ bởi tất cả instances của class.
  • Khởi tạo khi class được load (class loading), trước khi bất kỳ object nào được tạo.
  • Truy cập qua ClassName.variableName (khuyên dùng) hoặc instance.variableName (được nhưng warning).
  • Biến instance (non-static) mỗi object có bản sao riêng.

Ví dụ minh họa

public class Counter {
    // Static variable - chia sẻ bởi tất cả instances
    private static int instanceCount = 0;
    
    // Instance variable - mỗi object có bản sao riêng
    private int id;
    
    public Counter() {
        this.id = ++instanceCount; // Tăng counter khi tạo object mới
        System.out.println("Created instance #" + id + " (total: " + instanceCount + ")");
    }
    
    public static int getInstanceCount() {
        return instanceCount;
    }
    
    public int getId() { return id; }
    
    public static void main(String[] args) {
        System.out.println("Initial count: " + Counter.getInstanceCount()); // 0
        
        Counter c1 = new Counter(); // #1
        Counter c2 = new Counter(); // #2
        Counter c3 = new Counter(); // #3
        
        System.out.println("c1.id = " + c1.getId()); // 1
        System.out.println("c2.id = " + c2.getId()); // 2
        System.out.println("c3.id = " + c3.getId()); // 3
        System.out.println("Final count: " + Counter.getInstanceCount()); // 3
        
        // Truy cập static variable qua class name (best practice)
        Counter.instanceCount = 100; // Có thể truy cập nếu không private
        System.out.println("After manual set: " + Counter.getInstanceCount()); // 100
    }
}

Static Variable vs Instance Variable

Tiêu chíStatic Variable (Class Variable)Instance Variable
Khai báostatic type name;type name; (không có static)
Bộ nhớMetaspace (class metadata) / Heap (static field storage)Heap (bên trong object)
Số lượng bản sao1 cho toàn class1 cho mỗi instance
Khởi tạoKhi class load (static initializer)Khi object tạo (constructor)
Truy cậpClassName.var hoặc obj.varobj.var (cần instance)
Thread-safetyCần synchronization nếu mutableMỗi thread có object riêng → an toàn hơn
SerializationKhông được serialize (transient mặc định)Được serialize mặc định

Static Initialization Block

public class Config {
    static final String APP_NAME;
    static final int MAX_CONNECTIONS;
    static {
        // Khởi tạo phức tạp, đọc config file, v.v.
        APP_NAME = "MyApp";
        MAX_CONNECTIONS = loadFromConfig();
        System.out.println("Config loaded");
    }
    private static int loadFromConfig() { return 100; }
}

Best Practices

  • Dùng static final cho constants (naming: UPPER_SNAKE_CASE).
  • Tránh mutable static state (global state) – gây khó test, race condition, memory leak.
  • Nếu cần mutable shared state: dùng AtomicInteger, ConcurrentHashMap, hoặc encapsulate trong singleton thread-safe.
  • Static variable của generic class: class Box { static T item; } – KHÔNG được phép (type erasure).

Ví dụ thực tế: Singleton pattern

public class DatabaseConnection {
    private static volatile DatabaseConnection instance;
    private static final Object lock = new Object();
    
    private DatabaseConnection() { /* init connection */ }
    
    public static DatabaseConnection getInstance() {
        if (instance == null) {
            synchronized (lock) {
                if (instance == null) instance = new DatabaseConnection();
            }
        }
        return instance;
    }
}