1. Từ khóa static trong Java

Khi ta khai báo các thuộc tính, phương thức thì nó chỉ được sử dụng khi khởi tạo đối tượng, thông tin cũng thuộc đối tượng đó. Đôi khi, ta cần thông tin chung cho tất cả các đối tượng. Có nghĩa những thông tin đó lưu ở một vùng nhớ duy nhất. Và static sẽ giúp ta giải quyết vấn đề này.

Từ khóa static trong Java được sử dụng để quản lý bộ nhớ tốt hơn và nó có thể truy cập trực tiếp thông qua lớp mà không cần khởi tạo. Khi những thành viên bên trong một lớp có từ khóa static thì nó thuộc về lớp, không phải thuộc về riêng một đối tượng nào đó. Chúng ta có thể áp dụng từ khóa static với các biến, các phương thức, các khối, các lớp lồng nhau(nested class)

  • Biến static (static variables): khi khai báo một biến là static , thì biến đó được gọi là biến tĩnh, hay biến static
  • Phương thức static (static methods): khi bạn khai báo một phương thức là static , thì phương thức đó gọi là phương thức static
  • Khối static (static blocks): được sử dụng để khởi tạo thành viên dữ liệu static
  • Lớp static (static class): một class được có thể được đặt là static chỉ khi nó là một nested class. Một nested static class có thể được truy cập mà không cần một object của outer class (lớp bên ngoài).
  • Import static : từ phiên bản Java 5, cho phép import các thành viên tĩnh (static member) của một class hoặc package vào một class khác bằng cách sử dụng từ khóa import và sau đó sử dụng chúng như là thành viên của lớp đó.

2. Biến static trong Java – static variables

Đôi khi ta muốn một class có những biến dùng chung cho cả các đối tượng thuộc class đó. Ta gọi các biến dùng chung này là biến của lớp (class variable), hay gọi tắt là biến lớp. Chúng không gắn với bất cứ một đối tượng nào mà chỉ gắn với lớp đối tượng. Chúng được dùng chung cho tất cả các đối tượng trong lớp đó.

Để phân biệt giữa biến thực thể và biến lớp khi khai báo trong định nghĩa lớp, ta dùng từ khóa static cho các biến lớp. Vì từ khóa đó nên biến lớp thường được gọi là biến static hay biến tĩnh.

Ví dụ:

  • Khi không sử dụng biến static
class Student{  
     int rollno;  
     String name;  
     String college="Lập Trình Từ Đầu";  
}

Giả sử có 10000 người dùng, bây giờ instance của các dữ liệu thành viên sẽ sự dụng bộ nhớ mỗi khi đối tượng được tạo. Tất cả có rollnoname là thuộc tính riêng. Tuy nhiên, college là thuộc tính chung của tất cả đối tượng. Nếu chúng ta tạo nó là static , thì trường này sẽ chỉ sử dụng bộ nhớ một lần để lưu biến này.

  • Sử dụng biến static
public class Main {
    int rollno;
    String name;
    static String college = "Lập Trình Từ Đầu";
 
    Main(int r, String n) {
        rollno = r;
        name = n;
    }
 
    void display() {
        System.out.println(rollno + " - " + name + " - " + college);
    }
 
    public static void main(String args[]) {
        Main s1 = new Main(1, "Thành");
        Main s2 = new Main(2, "Nam");
 
        s1.display();
        s2.display();
    }
}

Kết quả

1 - Thành - Lập Trình Từ Đầu
2 - Nam - Lập Trình Từ Đầu

Việc cấp phát bộ nhớ cho biến static chỉ xảy ra một lần khi class được nạp vào bộ nhớ Giá trị mặc định khi khai báo và khởi tạo biến staticnon-static là giống nhau, cụ thể:

  • primitive integers (long, int, short, byte): 0
  • primitive floating points (double, float): 0.0
  • boolean: false
  • object references: null

Biến static có thể được sử dụng làm thuộc tính chung, để dùng chung dữ liệu cho tất cả objects (hoặc instances ) của lớp đó và điều đó giúp cho chương trình tiết kiệm bộ nhớ hơn

Nếu một biến vừa khai báo từ khóa final vừa khai báo từ khóa static thì nó được xem như là một hằng số. Một hằng số nên được viết hoa và nếu có nhiều từ thì phân cách bằng dấu gạch dưới (_)

Ví dụ: public static final PI = 3.14;

Trong Interface, mặc định một biến sẽ được khai báo là public static final. Nếu một biến được khai báo với từ khóa static thì ta có thể truy cập trực tiếp thông qua lớp.

3. Phương thức static trong Java – static methods

3.1. Sử dụng phương thức static

Nếu ta áp dụng từ khóa static với bất cứ phương thức nào, thì phương thức đó được gọi là phương thức static . Phương thức tĩnh cũng giống như biến tĩnh, có thể gọi mà không cần khởi tạo đối tượng. Phương thức tĩnh rất thích hợp cho những class thư viện viết sẵn, không cần khởi tạo mà chỉ cần gọi ra để chạy chương trình.

Phương thức static có một số đặc điểm như sau:

  • Một phương thức static thuộc lớp chứ không phải đối tượng của lớp.
  • Một phương thức static có thể được gọi mà không cần tạo khởi tạo (instance) của một lớp.
  • Phương thức static có thể truy cập biến static và có thể thay đổi giá trị của nó.
  • Một phương thức static chỉ có thể gọi một phương thức static khác, không thể gọi được một phương thức non-static.

Vậy khi nào ta sẽ sử dụng phương thức static? Khi phương thức không phụ thuộc vào trạng thái của đối tượng, nghĩa là không cần sử dụng bất kỳ dữ liệu thành viên nào của đối tượng, mọi thứ được truyền như các tham số (parameter). Các phương thức tiện ích là một trường hợp thường được sử dụng nhất trong Java vì chúng có thể được truy cập trực tiếp bằng tên lớp mà không cần tạo bất thể hiện nào. Ví dụ như lớp java.lang.Math là một ví dụ trường hợp sử dụng static method.

Ví dụ:

public class Main {
    int rollno;
    String name;
    static String college = "Lập Trình Từ Đầu";
 
    static void change() {
        // Thay đổi thuộc tính static (thuộc tính chung của tất cả các đối tượng)
        college = "Lập Trình Từ Đầu";
    }
 
    Main(int r, String n) {
        rollno = r;
        name = n;
    }
 
    void display() {
        System.out.println(rollno + " - " + name + " - " + college);
    }
 
    public static void main(String args[]) {
        Main.change();
 
        Main s1 = new Main(1, "Nam");
        Main s2 = new Main(2, "Sơn");
        Main s3 = new Main(3, "Thành");
 
        s1.display();
        s2.display();
        s3.display();
    }
}

Kết quả

1 - Nam - Lập Trình Từ Đầu
2 - Sơn - Lập Trình Từ Đầu
3 - Thành - Lập Trình Từ Đầu

3.2. Hạn chế việc sử dụng phương thức static

Sử dụng phương thức static cũng có một số hạn chế nhất định. Đầu tiên là Phương thức static không thể sử dụng biến non-static hoặc gọi trực tiếp phương thức non-static. Tiếp theo thì từ khóa thissuper không thể được sử dụng trong ngữ cảnh static.

  • Một phương thức static không thể được sử dụng từ khóa thissuper .
  • Người dùng không thể override (đè) phương thức static trong Java, bởi vì kỹ thuật đè (overriding) phương thức được dựa trên quá trình gán (binding) động khi khi chương trình đang chạy (runtime) và những phương thức static được gán tĩnh trong thời gian biên dịch. Phương thức tĩnh không ràng buộc với thực thể của lớp nên phương thức tĩnh sẽ không thể override (đè).

Ví dụ:

// Chương trình Java để chứng minh hạn chế đối với các phương thức tĩnh

class Main
{
    //biến static
    static int a = 10;
    
    // instance 
    int b = 20;
    
    // static method
    static void m1()
    {
        a = 20;
        System.out.println("from m1");
        
        // Không thể tạo tham chiếu tĩnh đến trường không tĩnh b
        b = 10; // compilation error
                
        // Không thể tạo tham chiếu tĩnh đến
                // Phương pháp không tĩnh m2 () từ phép thử điển hình
        m2(); // Lỗi
        
        // Không thể sử dụng super trong ngữ cảnh tĩnh
        System.out.println(super.a); // compiler error
    }
    
    // instance method
    void m2()
    {	
        System.out.println("from m2");
    }
    
    
    
    public static void main(String[] args)
    {
        // main method
    }
}

Kết quả: khá nhiều lỗi sẽ hiện ra!

4. Khối static trong Java – static blocks

Khối static được dùng để khởi tạo hoặc thay đổi giá trị của các biến static. Nó được thực thi trước phương thức main tại thời gian tải lớp. Một class có thể có nhiều static blocks. Khối sẽ được thực hiện khi lớp chứa nó được load vào trong bộ nhớ. Trong một lớp có thể nhiều khối tùy ý. Các khối này sẽ chạy cùng nhau, và chạy trước cả chương trình main của lớp đó.

Ví dụ:

public class Main {
    static {
        System.out.println("Khối static!");
    }
 
    public static void main(String args[]) {
        System.out.println("Main: Lập trình từ đầu !");
    }
}

Kết quả

Khối static!
Main: Lập trình từ đầu !

5. Lớp static trong Java – static class

Một class được có thể được đặt là static chỉ khi nó là một nested class (tức nằm trong một lớp khác). Một nested static class có thể được truy cập mà không cần một object của outer class (lớp bên ngoài).

Chúng ta không thể khai báo một lớp cấp cao nhất với một sửa đổi tĩnh nhưng có thể khai báo các lớp lồng nhau là tĩnh. Các loại lớp như vậy được gọi là các lớp tĩnh lồng nhau. Lớp tĩnh lồng nhau không cần tham chiếu của lớp bên ngoài. Trong trường hợp này, một lớp tĩnh không thể truy cập các thành viên không tĩnh của lớp ngoài.

Ví dụ:

public class Main {
  
    private static String str = "Laptrinhtudau.com";
  
    // Static class
    static class MyNestedClass {
        
        // non-static method
        public void disp(){ 
          System.out.println(str); 
        }
    }
    
    public static void main(String args[])
    {
        Main.MyNestedClass obj
            = new Main.MyNestedClass();
        obj.disp();
    }
}

Kết quả

Laptrinhtudau.com