การทำความเข้าใจคำอธิบายประกอบ Java – Java @annotations บทช่วยสอน
เผยแพร่แล้ว: 2019-10-22
คำอธิบายประกอบใช้ใน Java อย่างไรและที่ไหน
คำอธิบายประกอบในภาษาการเขียนโปรแกรมคอมพิวเตอร์ Java เป็นรูปแบบพิเศษของข้อมูลเมตาวากยสัมพันธ์ที่สามารถเพิ่มลงในซอร์สโค้ด Java
คลาส เมธอด ตัวแปร พารามิเตอร์ และแพ็คเกจอาจมีคำอธิบายประกอบ ต่างจากแท็ก Javadoc ตรงที่หมายเหตุประกอบ Java สามารถสะท้อนให้เห็นได้ว่าสามารถฝังลงในไฟล์คลาสที่สร้างโดยคอมไพเลอร์และอาจเก็บรักษาไว้โดย Java VM เพื่อให้สามารถดึงข้อมูลได้ในขณะใช้งาน
เป็นไปได้ที่จะสร้าง meta-annotation จากที่มีอยู่แล้วใน Java ซึ่งทำให้แนวคิดนี้ซับซ้อนมากขึ้น
Java กำหนดชุดของคำอธิบายประกอบที่สร้างขึ้นในภาษา

คำอธิบายประกอบที่ใช้กับโค้ดจาวา:
- @Override – ตรวจสอบว่าฟังก์ชันเป็นการแทนที่ ทำให้เกิดคำเตือนการคอมไพล์หากไม่พบฟังก์ชันในคลาสพาเรนต์ตัวใดตัวหนึ่ง
- @Deprecated – ทำเครื่องหมายฟังก์ชันว่าล้าสมัย ทำให้เกิดคำเตือนการคอมไพล์หากใช้ฟังก์ชัน
- @SuppressWarnings – สั่งให้คอมไพเลอร์ระงับคำเตือนเวลาคอมไพล์ที่ระบุในพารามิเตอร์คำอธิบายประกอบ
คำอธิบายประกอบที่ใช้กับคำอธิบายประกอบอื่นๆ:
- @ การเก็บรักษา – ระบุวิธีจัดเก็บคำอธิบายประกอบที่ทำเครื่องหมายไว้—ไม่ว่าจะเป็นในโค้ดเท่านั้น คอมไพล์ในคลาส หรือพร้อมใช้งานที่รันไทม์ผ่านการสะท้อน
- @Documented – ทำเครื่องหมายคำอธิบายประกอบอื่นเพื่อรวมไว้ในเอกสารประกอบ
- @Target – ทำเครื่องหมายคำอธิบายประกอบอื่นเพื่อจำกัดประเภทขององค์ประกอบ Java ที่คำอธิบายประกอบอาจนำไปใช้
- @Inherited – ทำเครื่องหมายคำอธิบายประกอบอื่นที่จะสืบทอดไปยังคลาสย่อยของคลาสที่มีคำอธิบายประกอบ (โดยค่าเริ่มต้นคำอธิบายประกอบจะไม่สืบทอดไปยังคลาสย่อย)
ลองดูสิ่งเหล่านี้ผ่านตัวอย่างตัวอย่าง:
1) @Override คำอธิบายประกอบ:
การมีอยู่ของมันบ่งชี้ให้คอมไพเลอร์ทราบว่าเมธอดที่มีคำอธิบายประกอบต้องแทนที่เมธอด superclass ที่มีอยู่
กรณีการใช้งานที่พบบ่อยที่สุดสำหรับ @Override นั้นใช้วิธี Object :
1 2 3 4 |
@ Override public int hashValue ( ) { System . out . Println ( "This method is using @Override Annotation" ) ; } |
สาเหตุหลักที่ @Override ถูกสร้างขึ้นเพื่อจัดการกับ ข้อผิดพลาดในการพิมพ์ อย่างง่าย
ตัวอย่างเช่น วิธีการประกาศผิดพลาดเป็น
1 |
public int hashvalue ( ) { . . . } |
อันที่จริงแล้ว ไม่ใช่ การแทนที่ – ชื่อเมธอดมีตัวพิมพ์ เล็กทั้งหมด ดังนั้นจึงไม่ตรงกับชื่อของ เมธอด hashValue() ทุกประการ อย่างไรก็ตามมันจะรวบรวมได้อย่างสมบูรณ์แบบ ข้อผิดพลาดดังกล่าวเกิดขึ้นได้ง่ายและจับได้ยาก ซึ่งเป็นการรวมกันที่อันตราย การใช้คำอธิบายประกอบ @Override จะช่วยป้องกันไม่ให้เกิดข้อผิดพลาดดังกล่าว
คุณควรจะมีนิสัยในการใช้ @Override ทุกครั้งที่คุณแทนที่เมธอด superclass

2) @ คำอธิบายประกอบที่เลิกใช้แล้ว:
คำอธิบายประกอบนี้บ่งชี้ว่าองค์ประกอบที่ทำเครื่องหมายถูก เลิกใช้ และไม่ควรใช้อีกต่อไป คอมไพเลอร์สร้างคำเตือนเมื่อใดก็ตามที่โปรแกรมใช้เมธอด คลาส หรือฟิลด์ที่มีคำอธิบายประกอบ @Deprecated
เมื่อเลิกใช้อิลิเมนต์ ควรจัดทำเอกสารโดยใช้แท็ก Javadoc @deprecated
ตามที่แสดงในตัวอย่างต่อไปนี้
1 2 3 4 |
< strong > @ Deprecated < / strong > static void deprecatedMethod ( ) { System . out . Println ( "This method is Deprecated.." ) ; } |
3) คำอธิบายประกอบ @SuppressWarnings:
แค่บอกคอมไพเลอร์อย่าตะโกน ฉันรู้ว่าฉันกำลังทำอะไร
1 2 3 4 |
@ SuppressWarnings ( "serial" ) public class OldCode implements Serializable { System . out . Println ( "This is Old Code.." ) ; } |
4) @Retention คำอธิบายประกอบ:
คำอธิบายประกอบการเก็บข้อมูลระบุตำแหน่งและระยะเวลาที่จะเก็บหมายเหตุประกอบที่มีประเภทนี้ไว้
มีสามค่า:
- RetentionPolicy.SOURCE — หมายเหตุประกอบประเภทนี้จะถูกเก็บรักษาไว้ที่ระดับต้นทางเท่านั้น และคอมไพเลอร์จะไม่สนใจ
- RetentionPolicy.CLASS —หมายเหตุประกอบประเภทนี้จะถูกคอมไพเลอร์เก็บไว้ ณ เวลาคอมไพล์ แต่ VM จะถูกละเว้น
- RetentionPolicy.RUNTIME — คำอธิบายประกอบประเภทนี้จะถูกเก็บรักษาโดย VM เพื่อให้สามารถอ่านได้เฉพาะขณะรันไทม์
1 2 3 4 |
@ Retention ( RetentionPolicy . RUNTIME ) public @ interface Crunchify_Retention { String returnSomething ( ) ; } |
5) @หมายเหตุประกอบ:
1 2 3 4 |
@ Documented public @ interface Crunchify_Documented { String writeDocument ( ) ; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public class DocumentedAnnotations { public static void main ( String arg [ ] ) { new DocumentedAnnotations ( ) . performRetention ( ) ; new DocumentedAnnotations ( ) . performDocumented ( ) ; } @ Crunchify_Retention ( returnSomething = "Hello retention test" ) public void performRetention ( ) { System . out . printf ( "Testing annotation 'Crunchify_Retention'" ) ; } @ Crunchify_Documented ( writeDocument = "Hello document" ) public void performDocumented ( ) { System . out . printf ( "Testing annotation 'Crunchify_Documented'" ) ; } } |
ตอนนี้ให้ลองเรียกใช้คำสั่ง Java Doc และดูผลลัพธ์

6) @Target คำอธิบายประกอบ:
Target ระบุว่าองค์ประกอบของโปรแกรมใดบ้างที่สามารถใส่คำอธิบายประกอบได้โดยใช้อินสแตนซ์ของประเภทคำอธิบายประกอบที่มีคำอธิบายประกอบ ค่าของ Target เป็นหนึ่งในสมาชิกของ java.lang.annotation.ElementType
enum:
- ANNOTATION_TYPE สามารถใช้ประเภทคำอธิบายประกอบที่มีคำอธิบายประกอบเพื่อประกาศประเภทคำอธิบายประกอบได้
- คอนสตรัคเตอร์ สามารถใช้ประเภทคำอธิบายประกอบที่มีคำอธิบายประกอบเพื่อใส่คำอธิบายประกอบการประกาศตัวสร้าง
- สนาม. สามารถใช้ประเภทคำอธิบายประกอบที่มีคำอธิบายประกอบเพื่อใส่คำอธิบายประกอบการประกาศฟิลด์
- LOCAL_VARIABLE. สามารถใช้ประเภทคำอธิบายประกอบที่มีคำอธิบายประกอบเพื่อใส่คำอธิบายประกอบการประกาศตัวแปรในเครื่องได้
- กระบวนการ. สามารถใช้ประเภทคำอธิบายประกอบที่มีคำอธิบายประกอบเพื่อใส่คำอธิบายประกอบการประกาศวิธีการ
- บรรจุุภัณฑ์. สามารถใช้ประเภทคำอธิบายประกอบที่มีคำอธิบายประกอบเพื่อใส่คำอธิบายประกอบการประกาศแพ็คเกจ
- พารามิเตอร์. สามารถใช้ประเภทคำอธิบายประกอบที่มีคำอธิบายประกอบเพื่อใส่คำอธิบายประกอบการประกาศพารามิเตอร์
- พิมพ์. สามารถใช้ประเภทคำอธิบายประกอบที่มีคำอธิบายประกอบเพื่อใส่คำอธิบายประกอบการประกาศประเภท
1 2 3 4 |
@ Target ( value = METHOD ) You can have multiple values in the Target annotation . @ Target ( value = { TYPE , FIELD , METHOD , PARAMETER , CONSTRUCTOR , LOCAL_VARIABLE } ) |
7) @Inherited คำอธิบายประกอบ:
ตามที่ชื่อได้ยิน ประเภทคำอธิบายประกอบ @Inherited
จะได้รับการสืบทอดโดยคลาสย่อยของประเภทที่มีคำอธิบายประกอบ
1 2 3 4 5 6 7 8 9 10 |
@ Inherited @ interface ForEveryone { } @ interface JustForMe { } @ ForEveryone @ JustForMe class Superclass { } class Subclass extends Superclass { } |
ในตัวอย่างนี้ Superclass
ได้รับการใส่คำอธิบายประกอบอย่างชัดแจ้งด้วยทั้ง @ForEveryone
และ @JustForMe
Subclass
ไม่ได้รับการทำเครื่องหมายอย่างชัดแจ้งด้วยคลาสใดคลาสหนึ่ง อย่างไรก็ตาม มันสืบทอด @ForEveryone
เพราะส่วนหลังมีคำอธิบายประกอบด้วย @Inherited
@JustForMe
ไม่ได้ใส่คำอธิบายประกอบ ดังนั้นจึงไม่ได้รับการสืบทอดโดย Subclass
นี่คือคำอธิบายประกอบระดับชั้นเรียน
