CodeGym /Blog Java /Ngẫu nhiên /10 điều bạn cần biết về công cụ sửa đổi tĩnh trong Java

10 điều bạn cần biết về công cụ sửa đổi tĩnh trong Java

Xuất bản trong nhóm
Trong Java, từ bổ nghĩa tĩnh có nghĩa là thứ gì đó liên quan trực tiếp đến một lớp: nếu một trường là tĩnh, thì nó thuộc về lớp đó; nếu một phương thức là tĩnh, thì nó thuộc về lớp. Do đó, bạn có thể sử dụng tên của lớp để gọi một phương thức tĩnh hoặc tham chiếu một trường tĩnh. Ví dụ: nếu counttrường là tĩnh trong Counterlớp, điều đó có nghĩa là bạn có thể tham chiếu biến có biểu thức sau: Counter.count. 10 điều bạn cần biết về static modifier trong Java - 1Tất nhiên, công cụ sửa đổi truy cập phải được xem xét. Ví dụ, privatecác trường chỉ có sẵn trong lớp mà chúng được khai báo. Và protectedcác trường có sẵn cho tất cả các lớp bên trong một gói, cũng như cho tất cả các lớp con của chúng bên ngoài gói. Giả sử Counterlớp có một increment()phương thức tĩnh có nhiệm vụ tăngcountcánh đồng. Để gọi phương thức này, bạn có thể sử dụng Counter.increment(). Không cần tạo một thể hiện của Counterlớp để truy cập một trường hoặc phương thức tĩnh. Đây là sự khác biệt cơ bản giữa các biến và phương thức tĩnh (lớp) và các biến và phương thức KHÔNG tĩnh (thể hiện). Một lưu ý quan trọng. Đừng quên rằng các thành viên tĩnh của lớp trực tiếp thuộc về lớp chứ không phải bất kỳ thể hiện nào của lớp. Tức là giá trị của countbiến tĩnh sẽ giống nhau cho tất cả Countercác đối tượng. Trong bài viết này, chúng ta sẽ xem xét các khía cạnh cơ bản của việc sử dụng công cụ sửa đổi tĩnh trong Java, cũng như một số tính năng sẽ giúp bạn hiểu các khái niệm lập trình chính.

Điều mà mọi lập trình viên nên biết về công cụ sửa đổi tĩnh trong Java.

Trong phần này, chúng ta xem xét các khía cạnh chính của việc sử dụng các phương thức, trường và lớp tĩnh. Hãy bắt đầu với các biến.
  1. Bạn KHÔNG THỂ truy cập các thành viên không tĩnh của một lớp trong ngữ cảnh tĩnh, chẳng hạn như một phương thức hoặc khối tĩnh. Biên dịch mã dưới đây sẽ dẫn đến lỗi:

    
    public class Counter {
    private int count;
    public static void main(String args []) {
       System.out.println(count); //  Compile time error
    }
    }
    

    Đây là một trong những lỗi phổ biến nhất của các lập trình viên Java, đặc biệt là những người mới. Vì mainphương thức là tĩnh và countbiến thì không, nên sử dụng printlnphương thức bên trong mainphương thức sẽ tạo ra "lỗi thời gian biên dịch".

  2. Không giống như các biến cục bộ, các trường và phương thức tĩnh KHÔNG có thread safetrong Java. Trong thực tế, đây là một trong những nguyên nhân thường gặp nhất của các vấn đề bảo mật trong lập trình đa luồng. Xem xét rằng mỗi phiên bản của một lớp tham chiếu cùng một bản sao của một biến tĩnh, một biến như vậy cần được bảo vệ hoặc "khóa" bởi lớp. Do đó, khi sử dụng các biến tĩnh, hãy đảm bảo rằng chúng hoạt động đúng cách synchronizedđể tránh các vấn đề như race conditions.

  3. Các phương thức tĩnh có một lợi thế thực tế là không cần phải tạo một đối tượng mới mỗi khi bạn muốn gọi chúng. Một phương thức tĩnh có thể được gọi bằng tên của lớp khai báo nó. Đó là lý do tại sao các phương pháp này là hoàn hảo cho factorycác phương pháp và utilityphương pháp. Lớp này java.lang.Mathlà một ví dụ tuyệt vời: hầu như tất cả các phương thức của nó là tĩnh. Các lớp tiện ích của Java được đánh dấu finalvì lý do tương tự.

  4. Một điểm quan trọng khác là bạn không thể ghi đè ( @Override) các phương thức tĩnh. Nếu bạn khai báo một phương thức như vậy trong một subclass, tức là một phương thức có cùng tên và chữ ký, bạn chỉ cần "ẩn" phương thức đó superclassthay vì ghi đè lên nó. Hiện tượng này được gọi là method hiding. Điều này có nghĩa là nếu một phương thức tĩnh được khai báo trong cả lớp cha và lớp con, thì phương thức được gọi sẽ luôn dựa trên loại biến tại thời điểm biên dịch. Không giống như ghi đè phương thức, các phương thức đó sẽ không được thực thi khi chương trình chạy. Hãy xem xét một ví dụ:

    
    class Vehicle {
         public static void kmToMiles(int km) {
              System.out.println("Inside the parent class / static method");
         } 
    }
    
    class Car extends Vehicle {
         public static void kmToMiles(int km) {
              System.out.println("Inside the child class / static method");
         } 
    }
    
    public class Demo {   
       public static void main(String args []) {
          Vehicle v = new Car();
           v.kmToMiles(10);
      }
    }
    

    Đầu ra bảng điều khiển:

    Bên trong lớp cha / phương thức tĩnh

    Mã chứng minh rõ ràng rằng mặc dù thực tế là đối tượng là một Carphương thức tĩnh trong Vehiclelớp được gọi, vì phương thức này được gọi tại thời điểm biên dịch. Và lưu ý rằng không có lỗi biên dịch!

  5. Hơn nữa, ngoài các lớp cấp cao nhất, bạn có thể khai báo các lớp tĩnh. Các lớp như vậy được gọi là nested static classes. Chúng rất hữu ích để cung cấp sự gắn kết tốt hơn. Một ví dụ nổi bật của một lớp tĩnh lồng nhau HashMap.Entrylà một cấu trúc dữ liệu bên trong HashMap. Điều đáng chú ý là, giống như các lớp bên trong, các lớp lồng tĩnh được khai báo trong một tệp .class riêng biệt. Như vậy, nếu bạn khai báo năm lớp lồng nhau trong lớp chính của mình, bạn sẽ có 6 tệp có phần mở rộng .class. Một ví dụ khác là khai báo của riêng chúng ta Comparator, chẳng hạn như một bộ so sánh tuổi ( AgeComparator) trong Employeelớp.

  6. Công cụ sửa đổi tĩnh cũng có thể được chỉ định trong một khối tĩnh, hay được gọi là "khối khởi tạo tĩnh", khối này được thực thi khi lớp được tải. Nếu bạn không khai báo một khối như vậy, Java sẽ thu thập tất cả các trường tĩnh vào một danh sách duy nhất và khởi tạo chúng khi lớp được tải. Một khối tĩnh KHÔNG THỂ ném các ngoại lệ được kiểm tra, nhưng nó có thể ném các ngoại lệ không được kiểm tra. Trong trường hợp này, một ExceptionInInitializerErrorsẽ xảy ra. Trong thực tế, bất kỳ ngoại lệ nào xảy ra trong quá trình khởi tạo các trường tĩnh sẽ được Java bao bọc trong lỗi này. Đây cũng là nguyên nhân phổ biến nhất của lỗi NoClassDefFoundError, bởi vì lớp sẽ không có trong bộ nhớ khi nó được tham chiếu.

  7. Thật hữu ích khi biết rằng các phương thức tĩnh được liên kết tại thời điểm biên dịch, không giống như liên kết của các phương thức ảo hoặc không tĩnh, được liên kết trong thời gian chạy khi được gọi trên một đối tượng thực. Theo đó, các phương thức tĩnh không thể bị ghi đè trong Java, vì tính đa hình không áp dụng cho chúng trong thời gian chạy. Đây là một hạn chế quan trọng cần xem xét khi khai báo một phương thức tĩnh. Làm như vậy chỉ có ý nghĩa khi không có khả năng hoặc nhu cầu ghi đè phương thức trong lớp con. Các phương thức xuất xưởng và các phương thức tiện ích là những ví dụ điển hình về việc sử dụng đúng công cụ sửa đổi tĩnh. Joshua Bloch chỉ ra một số lợi thế mà các phương thức tĩnh của nhà máy có được so với các hàm tạo trong cuốn sách Java hiệu quả của anh ấy, đây là cuốn sách bắt buộc phải đọc đối với mọi lập trình viên Java.

  8. Khởi tạo là một khía cạnh quan trọng của một khối tĩnh. Các trường hoặc biến tĩnh được khởi tạo sau khi lớp được tải vào bộ nhớ. Thứ tự khởi tạo là từ trên xuống dưới, theo thứ tự mà chúng được khai báo trong tệp nguồn của lớp Java. Vì các trường tĩnh được khởi tạo theo cách an toàn cho luồng nên quy trình này cũng được sử dụng để triển khai mẫu Singleton. Nếu bạn không sử dụng as Enuma Singletonvì lý do nào đó, thì bạn có một giải pháp thay thế tốt. Nhưng trong trường hợp này, bạn phải tính đến việc đây không phải là khởi tạo "lười biếng". Điều này có nghĩa là trường tĩnh sẽ được khởi tạo ngay cả TRƯỚC KHI ai đó "yêu cầu" nó. Nếu một đối tượng chiếm nhiều tài nguyên hoặc hiếm khi được sử dụng, thì việc khởi tạo nó trong một khối tĩnh sẽ không có lợi cho bạn.

  9. Trong quá trình tuần tự hóa, các trường tĩnh, giống như transientcác biến, không được tuần tự hóa. Thật vậy, nếu bạn lưu bất kỳ dữ liệu nào trong trường tĩnh, thì dữ liệu đó sẽ chứa giá trị ban đầu (mặc định) sau khi giải tuần tự hóa. Ví dụ: nếu một trường tĩnh là một int, giá trị của nó sẽ bằng 0 sau quá trình khử lưu huỳnh. Nếu loại của nó là float, giá trị sẽ là 0,0. Nếu trường là một Object, giá trị sẽ là null. Thành thật mà nói, đây là một trong những câu hỏi thường gặp nhất về tuần tự hóa trong các cuộc phỏng vấn cho các vị trí Java. Không lưu trữ dữ liệu đối tượng thiết yếu trong một trường tĩnh!

  10. Cuối cùng, hãy nói về nhập tĩnh. Công cụ sửa đổi này có nhiều điểm chung với importcâu lệnh tiêu chuẩn, nhưng nó khác ở chỗ nó cho phép bạn nhập một hoặc tất cả các thành viên lớp tĩnh. Khi các phương thức tĩnh được nhập vào, chúng có thể được truy cập như thể chúng được khai báo trong cùng một lớp. Tương tự, bằng cách nhập các trường tĩnh, chúng ta có thể truy cập chúng mà không cần chỉ định tên lớp. Tính năng này xuất hiện trong Java 1.5 và cải thiện khả năng đọc mã khi được sử dụng đúng cách. Cấu trúc này được tìm thấy thường xuyên nhất trong các thử nghiệm JUnit, vì hầu hết tất cả các nhà phát triển thử nghiệm đều sử dụng nhập tĩnh cho các phương thức xác nhận, ví dụ: assertEquals()và các biến thể quá tải của chúng.

  11. Đó là tất cả cho bây giờ. Mọi lập trình viên Java cần biết tất cả các khía cạnh của công cụ sửa đổi tĩnh được đề cập ở trên. Bài viết này đã xem xét thông tin cơ bản về các biến tĩnh, trường, phương thức, khối khởi tạo và nhập. Nó cũng đề cập đến một số thuộc tính quan trọng cần biết để viết và hiểu các chương trình Java. Tôi hy vọng rằng mọi nhà phát triển sẽ hoàn thiện việc sử dụng khéo léo các thành viên tĩnh của họ, bởi vì nó rất quan trọng đối với sự phát triển phần mềm nghiêm túc."

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION