Bỏ qua để đến nội dung

static và instance members

1. Instance member - thuộc về từng đối tượng riêng

Phần tiêu đề “1. Instance member - thuộc về từng đối tượng riêng”

Mặc định, field và method thuộc về từng đối tượng (instance) - mỗi đối tượng có bản sao dữ liệu riêng:

public class Counter {
int count; // instance field - MỖI đối tượng có "count" riêng
void increment() { // instance method - phải gọi qua một đối tượng cụ thể
count++;
}
}
Counter c1 = new Counter();
Counter c2 = new Counter();
c1.increment();
c1.increment();
c2.increment();
System.out.println(c1.count); // 2 - riêng của c1
System.out.println(c2.count); // 1 - riêng của c2, không liên quan đến c1

Thêm từ khóa static khiến field/method thuộc về cả lớp, chỉ có một bản duy nhất, dùng chung cho mọi đối tượng:

public class Counter {
static int totalCounters = 0; // static field - CHỈ MỘT bản, dùng chung cho mọi đối tượng
int count;
public Counter() {
totalCounters++; // mỗi lần tạo đối tượng mới, tăng biến đếm dùng chung
}
}
Counter c1 = new Counter();
Counter c2 = new Counter();
Counter c3 = new Counter();
System.out.println(Counter.totalCounters); // 3 - đếm được tổng số đối tượng đã tạo

Static member nên được truy cập qua tên lớp, không cần (và không nên) qua một đối tượng cụ thể:

System.out.println(Counter.totalCounters); // ĐÚNG cách - qua tên lớp
Counter c = new Counter();
System.out.println(c.totalCounters); // Vẫn chạy được nhưng KHÔNG khuyến khích - dễ gây hiểu nhầm

4. Static method không truy cập được instance member

Phần tiêu đề “4. Static method không truy cập được instance member”

⚠️ Một static method không có một đối tượng cụ thể đi kèm, nên nó không thể truy cập trực tiếp instance field/method (vì Java không biết “instance nào”):

public class Counter {
int count; // instance field
static int totalCounters; // static field
static void printTotal() {
System.out.println(totalCounters); // OK - static truy cập static
// System.out.println(count); // LỖI BIÊN DỊCH! Không biết count của đối tượng nào
}
}

Ngược lại, instance method truy cập được cả static lẫn instance member bình thường.

5. static với phương thức tiện ích (utility method)

Phần tiêu đề “5. static với phương thức tiện ích (utility method)”

static rất phổ biến cho các phương thức không phụ thuộc trạng thái của một đối tượng cụ thể - ví dụ các hàm trong Math:

public class MathUtils {
static int square(int n) { return n * n; } // không cần trạng thái đối tượng nào
}
int result = MathUtils.square(5); // gọi trực tiếp qua tên lớp, không cần "new MathUtils()"
  • Instance member: thuộc về từng đối tượng riêng, mỗi đối tượng có bản sao dữ liệu độc lập
  • Static member: thuộc về cả lớp, chỉ có một bản duy nhất, dùng chung cho mọi đối tượng
  • Truy cập static member qua tên lớp; static method không truy cập trực tiếp được instance member
  • static phù hợp cho phương thức tiện ích, hằng số dùng chung, hoặc dữ liệu đếm/theo dõi ở cấp lớp