ในปี 2548 ด้วยการมาถึงของ Java 5 เราได้รู้จักเอนทิตีใหม่ที่เรียกว่าคำอธิบายประกอบ

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

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

ไวยากรณ์:


@Override
public int hashCode() {
      return super.hashCode();
}

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

เพื่อให้เข้าใจถึงวิธีการทำงานของคำอธิบายประกอบ เรามาทำความรู้จักกับแนวคิดของอินเทอร์เฟซตัวทำเครื่องหมายกันก่อน นับตั้งแต่การกำเนิดของ Java นักพัฒนาต้องการวิธีการทำเครื่องหมายคลาสเสมอเพื่อดำเนินการบางอย่างกับคลาสเหล่านั้น

ก่อน Java 5 พวกเขาใช้อินเทอร์เฟซที่ไม่ได้ทำในสิ่งที่เราคาดหวังให้อินเทอร์เฟซทำ ไม่มีวิธีการและไม่มีสัญญา มันเพิ่งทำเครื่องหมายชั้นเรียนว่าพิเศษไม่ทางใดก็ทางหนึ่ง

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

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

คำอธิบายประกอบกับส่วนต่อประสานเครื่องหมาย:


@MyAnnotation
public class MyClass {}

public class MyClass implements MarkerInterface {}

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

หากเราใช้อินเทอร์เฟซ เราจะทำเครื่องหมายคลาส หากเราใช้ไม่ถูกต้องและเกิดข้อผิดพลาด เราจะพบปัญหาตอนคอมไพล์และโปรแกรมจะไม่ทำงาน

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

โปรดทราบว่าหากเราต้องการทำเครื่องหมายคลาสเพื่อใช้ในอนาคต อินสแตนซ์ของคลาสนั้นจะต้องถูกส่งผ่านไปยังเมธอดเฉพาะ:


public class MyInteger implements Sum {}
interface Sum {};

public static void main(String[] args) throws IOException {
        increase(new MyInteger());
}
 
public static void increase(Sum count) {
        // TODO
}

ส่วนต่อประสานเครื่องหมายทำงานได้ดีที่สุดที่นี่

วิธีที่ดีที่สุดคือใช้คำอธิบายประกอบเมื่อเราต้องการบางอย่างเพิ่มเติม เช่น พารามิเตอร์ที่รองรับคำอธิบายประกอบ

ลองดูคำอธิบายประกอบมาตรฐานใน JDK:

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

@Override
public int hashCode() {
        return super.hashCode();
}
@เลิกใช้แล้ว ทำเครื่องหมายรหัสว่าเลิกใช้แล้ว

@Deprecated
public abstract void method();
@SuppressWarnings ปิดใช้งานคำเตือนของคอมไพเลอร์สำหรับองค์ประกอบที่มีคำอธิบายประกอบ โปรดทราบว่าหากคุณต้องการปิดใช้งานคำเตือนหลายหมวดหมู่ จะต้องอยู่ในวงเล็บปีกกา เช่น@SuppressWarnings({"unchecked", "cast"} )

public class DocumentsFolder {
   private List documents;

   @SuppressWarnings("unchecked")
public void addDocument(String document) {
            documents.add(document);
   }
}

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

อีกตัวอย่างที่มีหลายอาร์กิวเมนต์:


@SuppressWarnings({"unchecked", "deprecated"})