Tạo chú thích là một quá trình khá đơn giản, mặc dù nó bị giới hạn bởi một số quy tắc. Bây giờ chúng ta cần tìm ra mục đích thực tế mà chúng phục vụ.

Hãy nhớ lại cách chúng ta tạo chú thích của riêng mình.

Chúng tôi sẽ viết một chú thích dành cho các lớp và phương thức và chứa thông tin về tác giả và phiên bản của mã:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Info {
   String author() default "Author";
   String version() default "0.0";
}

Đây là các lớp của chúng tôi mà chúng tôi đã chú thích:

@Info
public class MyClass1 {
   @Info
   public void myClassMethod() {}
}

@Info(version = "2.0")
public class MyClass2 {
   @Info(author = "Anonymous")
   public void myClassMethod() {}
}

@Info(author = "Anonymous", version = "2.0")
public class MyClass3 {
   @Info(author = "Anonymous", version = "4.0")
   public void myClassMethod() {}
}

Làm thế nào chúng ta có thể sử dụng dữ liệu này trong thời gian chạy?

Bằng cách sử dụng sự phản chiếu để trích xuất siêu dữ liệu từ các chú thích. Nhắc lại thế nào là phản xạ. Phản ánh là một cơ chế để kiểm tra dữ liệu về một chương trình trong thời gian chạy. Phản chiếu cho phép bạn lấy thông tin về các trường, phương thức, hàm tạo lớp và lớp.

Chúng tôi sẽ sử dụng sự phản chiếu để đọc các chú thích trong một lớp và hiển thị thông tin mà chúng tôi muốn.

Chúng tôi sẽ đọc dữ liệu từ các lớp của chúng tôi trong phương thức chính :

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;

public class Main {
   public static void main(String[] args) throws NoSuchMethodException {
       readMyClass(MyClass1.class);
       readMyClass(MyClass2.class);
       readMyClass(MyClass3.class);
   }

   static void readMyClass(Class<?> myClassObj) throws NoSuchMethodException {
       System.out.println("\nClass: " + myClassObj.getName());
       readAnnotation(myClassObj);
       Method method = myClassObj.getMethod("myClassMethod");
       readAnnotation(method);
   }

   static void readAnnotation(AnnotatedElement element) {
       try {
           System.out.println("Search for annotations in " + element.getClass().getName());
           Annotation[] annotations = element.getAnnotations();
           for (Annotation annotation : annotations) {
               if (annotation instanceof Info) {
                   final Info fileInfo = (Info) annotation;
                   System.out.println("Author: " + fileInfo.author());
                   System.out.println("Version: " + fileInfo.version());
               }
           }
       } catch (Exception e) {
           e.printStackTrace();
       }
   }
}

Chúng tôi chuyển một thể hiện của lớp của chúng tôi sang phương thức readMyClass .

Sau đó, chúng ta có thể truyền một lớp cũng như một phương thức cho phương thức readAnnotation . Hãy làm điều đó — chúng ta sẽ truyền một đối tượng Lớp và một đối tượng Phương thức. Nó nhận một đối tượng cài đặt giao diện AnnotatedElement . Điều này cho phép chúng tôi lấy danh sách các chú thích từ đối tượng và nhận thông tin về từng chú thích.

Lưu ý rằng chúng tôi chỉ nhận được thông tin sau khi kiểm tra xem chú thích có thuộc loại chú thích của chúng tôi hay không: if (annotation instanceof Info) .

Đầu ra của chương trình cung cấp cho chúng tôi thông tin đầy đủ từ các chú thích:

Lớp: annotation.MyClass1
Tìm kiếm chú thích trong java.lang.Class
Tác giả: Tác giả
Phiên bản: 0.0
Tìm kiếm chú thích trong java.lang.reflect.Method
Tác giả: Tác giả
Phiên bản: 0.0

Lớp: annotation.MyClass2
Tìm kiếm chú thích trong java.lang. Lớp
Tác giả: Tác giả
Phiên bản: 2.0
Tìm kiếm chú thích trong java.lang.reflect.Method
Tác giả: Anonymous
Phiên bản: 0.0

Lớp: annotation.MyClass3
Tìm kiếm chú thích trong java.lang.Class
Tác giả: Anonymous
Phiên bản: 2.0
Tìm kiếm chú thích trong java. lang.reflect.Method
Tác giả: Anonymous
Phiên bản: 4.0

Do đó, với sự trợ giúp của phản ánh, chúng tôi có thể trích xuất siêu dữ liệu.

Bây giờ, hãy xem một ví dụ về việc sử dụng chú thích để cải thiện mã, bao gồm tăng khả năng đọc, tốc độ và chất lượng nói chung. Lombok sẽ giúp chúng tôi với điều này.

Lombok là một plugin trình biên dịch sử dụng chú thích để ẩn một lượng lớn mã và mở rộng ngôn ngữ, do đó đơn giản hóa việc phát triển và thêm một số chức năng.

Xem xét một ví dụ về chú thích từ Lombok:

@ToString Tạo triển khai phương thức toString() bao gồm biểu diễn kỹ lưỡng đối tượng: tên lớp, tất cả các trường và giá trị của chúng.
@ToString
public class Example
@EqualsAndHashCode Tạo các triển khai bằngmã băm sử dụng các trường không tĩnh và không tĩnh theo mặc định, nhưng có thể định cấu hình. Thông tin chi tiết có thể được tìm thấy trên trang web của dự án . Ở đó, bạn sẽ tìm thấy một ví dụ sử dụng @EqualsAndHashCode và cũng hiển thị cách triển khai tiêu chuẩn mà không cần chú thích.
@Getter / @Setter Tạo getters và setters cho các trường riêng tư.
@Getter
@Setter
private String name = "name";
@NonNull Được sử dụng để khẳng định rằng các trường không rỗng khi một đối tượng được khởi tạo. Nếu không, một NullPulumException sẽ bị ném.
public Example(@NonNull P p) {
 super("Hello");
 this.name = p.getName();
}

Lombok có nhiều chú thích hữu ích hơn nhưng ít được sử dụng hơn. Chúng tôi đã xem xét các chú thích đơn giản nhất của nó. Bạn có thể đọc thêm về dự án trên trang web chính thức .