การสร้างคำอธิบายประกอบเป็นกระบวนการที่ค่อนข้างง่าย แม้ว่าจะถูกจำกัดด้วยกฎบางประการ ตอนนี้เราต้องค้นหาว่าพวกมันมีจุดประสงค์เชิงปฏิบัติอะไรบ้าง

ลองนึกถึงวิธีที่เราสร้างคำอธิบายประกอบของเราเอง

เราจะเขียนคำอธิบายประกอบสำหรับคลาสและเมธอด และมีข้อมูลเกี่ยวกับผู้เขียนโค้ดและเวอร์ชัน:

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

นี่คือชั้นเรียนของเราที่เราใส่คำอธิบายประกอบ:

@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() {}
}

เราจะใช้ข้อมูลนี้ในขณะรันไทม์ได้อย่างไร

โดยใช้การสะท้อนเพื่อดึงข้อมูลเมตาจากคำอธิบายประกอบ จำได้ว่าภาพสะท้อนคืออะไร การสะท้อนกลับเป็นกลไกในการตรวจสอบข้อมูลเกี่ยวกับโปรแกรมในขณะรันไทม์ การสะท้อนช่วยให้คุณได้รับข้อมูลเกี่ยวกับฟิลด์ เมธอด ตัวสร้างคลาส และคลาส

เราจะใช้การสะท้อนเพื่ออ่านคำอธิบายประกอบในชั้นเรียนและแสดงข้อมูลที่เราต้องการ

เราจะอ่านข้อมูลจากชั้นเรียนของเราด้วย วิธีการ หลัก :

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();
       }
   }
}

เราส่งตัวอย่างคลาสของเราไปยังเมธอดreadMyClass

จากนั้นเราสามารถส่งคลาสและเมธอดไปยังเมธอดreadAnnotation ลองทำดู — เราจะส่งวัตถุคลาสและวัตถุเมธอด ใช้วัตถุที่ใช้อินเทอร์เฟซAnnotatedElement ซึ่งช่วยให้เราได้รับรายการคำอธิบายประกอบจากวัตถุและรับข้อมูลเกี่ยวกับแต่ละรายการ

โปรดทราบว่าเราจะได้รับข้อมูลหลังจากตรวจสอบว่าคำอธิบายประกอบอยู่ในประเภทคำอธิบายประกอบของเราเท่านั้น: if (annotation instanceof Info)

ผลลัพธ์ของโปรแกรมจะให้ข้อมูลที่สมบูรณ์จากคำอธิบายประกอบ:

Class: annotation.MyClass1
ค้นหาคำอธิบายประกอบใน java.lang.Class
Author: Author
Version: 0.0
ค้นหาคำอธิบายประกอบใน java.lang.reflect.Method
Author: Author
Version: 0.0

Class: annotation.MyClass2
ค้นหาคำอธิบายประกอบใน java.lang Class
Author: Author
Version: 2.0
ค้นหาคำอธิบายประกอบใน java.lang.reflect.Method
Author: Anonymous
Version: 0.0

Class: annotation.MyClass3
ค้นหาคำอธิบายประกอบใน java.lang.Class
Author: Anonymous
Version: 2.0
ค้นหาคำอธิบายประกอบใน java lang.reflect.Method
ผู้เขียน: ไม่ระบุ
ชื่อ เวอร์ชัน: 4.0

ดังนั้น ด้วยความช่วยเหลือของการสะท้อนกลับ เราจึงสามารถแยกข้อมูลเมตาได้

ตอนนี้ มาดูตัวอย่างการใช้คำอธิบายประกอบเพื่อปรับปรุงโค้ด ซึ่งรวมถึงการเพิ่มความสามารถในการอ่าน ความเร็ว และคุณภาพโดยทั่วไป ลอมบอกจะช่วยเราในเรื่องนี้

Lombok เป็นปลั๊กอินคอมไพเลอร์ที่ใช้คำอธิบายประกอบเพื่อซ่อนโค้ดจำนวนมากและขยายภาษา ทำให้การพัฒนาง่ายขึ้นและเพิ่มฟังก์ชันบางอย่าง

พิจารณาตัวอย่างคำอธิบายประกอบจากลอมบอก:

@ToString สร้างการใช้งานเมธอดtoString()ที่ประกอบด้วยการแสดงออบเจกต์อย่างละเอียด: ชื่อคลาส ฟิลด์ทั้งหมด และค่าต่างๆ
@ToString
public class Example
@EqualsAndHashCode สร้างการใช้งานเท่ากับและhashCodeที่ใช้ฟิลด์ที่ไม่คงที่และไม่คงที่ตามค่าเริ่มต้น แต่สามารถกำหนดค่าได้ สามารถดูรายละเอียดเพิ่มเติมได้ที่เว็บไซต์ของโครงการ คุณจะพบตัวอย่างที่ใช้@EqualsAndHashCodeและแสดงการใช้งานมาตรฐานโดยไม่มีคำอธิบายประกอบ
@เก็ตเตอร์ / @เซ็ตเตอร์ สร้าง getters และ setters สำหรับฟิลด์ส่วนตัว
@Getter
@Setter
private String name = "name";
@NonNull ใช้เพื่อยืนยันว่าฟิลด์ไม่เป็นโมฆะเมื่อวัตถุถูกสร้างอินสแตนซ์ มิฉะนั้นNullPointerExceptionจะถูกส่งออกไป
public Example(@NonNull P p) {
 super("Hello");
 this.name = p.getName();
}

ลอมบอกมีคำอธิบายประกอบที่เป็นประโยชน์มากมายซึ่งใช้ไม่บ่อยนัก เราได้พิจารณาคำอธิบายประกอบที่ง่ายที่สุดแล้ว คุณสามารถอ่านเพิ่มเติมเกี่ยวกับโครงการได้ที่เว็บไซต์ทางการ