自定義註解以及獲取註解
一、前言
註解(Annotation)作為元資料的載體,為程式程式碼本身提供額外的資訊,使用過MyBatis等ORM框架的朋友對 @Insert 的註解應該不陌生了,這是MyBatis自定義的註解,顯然我們也可以按需求自定義一些註解,然後對其進行解析獲取元資料,進而實現通過程式碼生成程式碼的操作。
二、自定義註解
只需通過 關鍵字@interface 即可自定義註解
// 標識註解(就是無屬性的註解) public @interface AnnotationWithoutProperty{ }// 帶value屬性的註解 public @interface AnnotationWithVal{ String value(); } // 帶myVal屬性的註解 public @interface AnnotationWithMyVal{ String[] myValue(); } // 帶value和myVal屬性的註解 public @interface AnnotationWith2Val{ String value(); String[] myValue(); } // 帶預設值的myVal屬性的註解 public @interface AnnotationWithDefaultVal{ String myVal()default "hello world!"; }
使用方式如下:
@AnnotationWithoutProperty @AnnotationWithVal("hello world") // value屬性賦值時,不用顯式寫出屬性名 @AnnotationWithMyVal(myValue={"hello", "world"}) // 其他屬性賦值時,必須顯示寫出屬性名 @AnnotationWith2Val(value="hello world", myVal={"hello", "world"}) @AnnotationWithDefaultVal // 屬性擁有預設值時,不必顯示設定屬性值@AnnotationWithDefaultVal("new value") public void test(){}
三、註解的註解
註解的註解就是為註解本身提供額外的資訊,從而約束或增強註解的能力。其中包含有 @Documented 、 @Inherited 、 @Target 、 Retention 4種註解。
@Target註解 :用於約束被描述的註解的使用範圍,當被描述的註解超出使用範圍則編譯失敗。
1.CONSTRUCTOR:用於描述構造器
2.FIELD:用於描述域
3.LOCAL_VARIABLE:用於描述區域性變數
4.METHOD:用於描述方法
5.PACKAGE:用於描述包
6.PARAMETER:用於描述引數
7.TYPE:用於描述類、介面(包括註解型別) 或enum宣告
// 約束@MyAnnotation的作用範圍是函式和建構函式 @Target(ElementType.METHOD, ElementType.CONSTRUCTOR) public @interface MyAnnotation{}
@Retention註解 :用於約束被描述的註解的作用範圍,註解的作用範圍有三個,分別為
1. RetentionPolicy.SOURCE ,作用範圍為原始碼,就是僅存在於java檔案中,當執行 javac 命令時將會去除該註解。
2. RetentionPolicy.CLASS ,作用範圍為二進位制碼,就是存在於class檔案中,當執行 java 命令時會去除該註解。
3. RetentionPolicy.RUNTIME ,作用範圍為執行時,就是我們可以通過反射動態獲取該註解。
@Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation{}
@Documented註解 :用於指定javadoc生成API文件時顯示該註解資訊
@Inherited註解 :用於指定被描述的註解可以被其所描述的類的子類繼承。預設情況
// 預設註解不會被子類繼承 @MyAnnotation public class Parent{} // Son並沒有繼承註解MyAnnotation public class Son extends Parent{}
通過 @Inherited 子類將會繼承父類的 @MyAnnoation註解 。
四、讀取註解
通過反射我們可以獲取類、函式等上的註解資訊。
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.CLASS) @Documented public @interface MyAnnotaion{ String value() default "hello world"; } @MyAnnotation public class Test{ public static void main(String[] args){ MyAnnotation ma = Test.class.getAnnotation(MyAnnotation.class); System.out.println(ma.value()); // 獲取自身和從父類繼承的註解 Annotation[] annotations = Test.class.getAnnotations(); // 僅獲取自身的註解 Annotation[] annotations = Test.class.getDeclaredAnnotations(); } }