Đôi khi các thành phần static ta cần phải định nghĩa các thành phần lớp được sử dụng độc lập với bất kỳ đối tượng nào của lớp. Thông thường một thành phần của lớp phải được truy xuất thông qua đối tượng của lớp. Tuy nhiên, ta có thể có thể tạo ra một thành phần mà được sử dụng độc lập. Để tạo ra một thành phần như vậy trước khai báo của mỗi thành phần ta đặt một từ khóa static. Khi một thành phần được khai báo static, nó có thể được truy xuất trước khi một đối tượng được tạo ra và không cần tham chiếu tới bất kỳ đối tượng nào. Các thành phần static bao gồm: biến static, phương thức static, khối static.
• Biến static
Biến static về cơ bản là biến tổng thể. Khi các đối tượng của một lớp được khai báo, không có bản sao của biến đối tượng nào được tạo ra. Thay vào đó, tất cả các đối tượng cùng chung một biến static.
Ví dụ về biến static
class StaticVariable { static int count=20;
StaticVariable(){ count++; }
public static void main(String[] args) {
StaticVariable c1=new StaticVariable(); System.out.println("Bien dem count="+count); StaticVariable c2=new StaticVariable(); System.out.println("Bien dem count="+count); StaticVariable c3=new StaticVariable(); System.out.println("Bien dem count="+count); }
}
Biến count được khai báo là static nên nó chỉ có một bản sao trong mọi đối tượng, vì vậy khi đối tượng được tạo ra thì các biến count được tăng lên 1 do trong hàm constructor biến count được tăng lên 1.
• Phương thức static
Các phương thức được khai báo static có một số hạn chế sau:
o Chúng chỉ truy xuất tới các dữ liệu static o Chúng không thể tham chiếu tới this và super
Ví dụ
class StaticMethod {
public static void main(){
System.out.println("Hello"); }
public static void main(String[] args) {
main();
System.out.println("Hello World!"); }
}
Trong ví dụ này ta thấy khai báo hai phương thức main đều là phương thức tĩnh. Phương thức main này gọi tới phương thức main khác.
• Khối static
Nếu cần tính toán để khởi tạo các biến static, ta có thể khai báo khối static để nó có thể xử lý ngay tức thời khi lớp lần đầu tiên được tải vào bộ nhớ. Các khối static luôn được xử lý trước Ví dụ class StaticDemo { static{ System.out.println("Khoi static 1"); }
public static void main(String[] args) { System.out.println("Hello World!"); } static { System.out.println("Khoi static 2"); } }
Vì khối static luôn được xử lý trước nên kết quả in ra của chương trình trên sẽ là: Khoi static 1 Hello World! Khoi static 2 2.4.6. Các thành phần final • Biến final
Một biến được khai báo final. Làm như vậy sẽ ngăn ngừa nội dung của biến bị sửa đổi. Điều này nghĩa là ta phải khai báo một biến final khi nó được khai báo.
Ví dụ
final double pi=3.1416; • Sử dụng final với thừa kế
Mặc dù nạp chồng phương thức là một trong các đặc trưng mạnh của Java, nhưng sẽ có những lúc ta cần ngăn ngừa điều này xảy ra. Để không cho phép một phương thức được nạp chồng, xác định từ khóa final như là một bổ từ tại đầu mỗi khai báo của nó. Các phương thức được khai báo là final không thể được nạp chồng.
Ví dụ
class A {
final void method(){ }
}
class B extends A{ final void method(){ }
}
Khai báo lớp B có lỗi, vì ở lớp A, phương thức method đã được khai báo với từ khóa final nên nó không thể được nạp chồng trong lớp B.
Sử dụng từ khóa final để cấm thừa kế
Đôi khi ta cần cấm một số lớp không có lớp con. Ta có thể thực hiện điều này bằng cách khai báo lớp với từ khóa final.
Ví dụ
final class A { }
Lúc này, các lớp khác không thể thừa kế từ lớp A.