至於關於編譯時的註解,待下篇博客的時候會結合例子講解一下,目前我也正在學習當中java
提到註解,大多數人應該都不默認,在咱們程序中見到的@Override,@Deprected,@SupressWarnings等等,這些都是註解,只不過是系統本身封裝好的,而咱們平時比較少去深刻理解是怎樣實現的?程序員
Annotation(註解)就是Java提供了一種元程序中的元素關聯任何信息和着任何元數據(metadata)的途徑和方法。Annotion(註解)是一個接口,程序能夠經過反射來獲取指定程序元素的Annotion對象,而後經過Annotion對象來獲取註解裏面的元數據。面試
根據註解參數的個數,咱們能夠將註解分爲三類:segmentfault
根據註解使用方法和用途,咱們能夠將Annotation分爲三類:數組
元註解的做用就是負責註解其餘註解。Java5.0定義了4個標準的meta-annotation類型,它們被用來提供對其它annotation類型做說明。Java5.0定義的元註解:微信
SOURCE(源碼時),CLASS(編譯時),RUNTIME(運行時),默認爲 CLASS,SOURCE 大都爲 Mark Annotation,這類 Annotation 大都用來校驗,好比 Override, SuppressWarnings
@Target 能夠用來修飾哪些程序元素,如 TYPE, METHOD, CONSTRUCTOR, FIELD, PARAMETER 等,未標註則表示可修飾全部ide
ANONOTATION_TYPE(註解類型聲明),
PACKAGE(包)
TYPE (類,包括enum及接口,註解類型)
METHOD (方法)
CONSTRUCTOR (構造方法)
FIFLD (成員變量)
PARAMATER (參數)
LOCAL_VARIABLE (局部 變量)
元數據從metadata一詞譯來,就是「關於數據的數據」的意思。
元數據的功能做用有不少,好比:你可能用過Javadoc的註釋自動生成文檔。這就是元數據功能的一種。總的來講,元數據能夠用來建立文檔,跟蹤代碼的依賴性,執行編譯時格式檢查,代替已有的配置文件。若是要對於元數據的做用進行分類,目前尚未明確的定義,不過咱們能夠根據它所起的做用,大體可分爲三類:函數
其餘知識點暫時不介紹,我的以爲一會兒介紹太多概念很難消化。下面讓咱們一塊兒結合例子來使用它。學習
自定義註解大概可分爲如下三個步驟:測試
這些類型和它們所支持的類在java.lang.annotation包中能夠找到。
/* * 定義註解 MethodInfo * 爲方便測試:註解目標爲類 方法,屬性及構造方法 * 註解中含有三個元素 id ,name和 gid; * id 元素 有默認值 0 */ @Documented @Target({ElementType.TYPE,ElementType.METHOD, ElementType.FIELD,ElementType.CONSTRUCTOR}) @Retention(RetentionPolicy.RUNTIME) @Inherited public @interface MethodInfo { String name() default "xujunTest"; int id() default 0; Class<Long> gid(); }
a. 全部方法沒有方法體,沒有參數沒有修飾符,實際只容許 public & abstract 修飾符,默認爲 public,不容許拋異常
b. 方法返回值只能是基本類型,String, Class, annotation, enumeration 或者是他們的一維數組
c. 若只有一個默認屬性,可直接用 value() 函數。一個屬性都沒有表示該 Annotation 爲 Mark Annotation
String name() default "xujunTest";
/** * 這個類專門用來測試註解使用 * @author xujun */ //類成員註解 @MethodInfo (name="type",gid=Long.class) public class UserAnnotation { //類成員註解 @TestA(name="param",id=1,gid=Long.class) private Integer age; //構造方法註解 @TestA (name="construct",id=2,gid=Long.class) public UserAnnotation(){ } //類方法註解 @TestA(name="public method",id=3,gid=Long.class) public void a(){ Map<String,String> m = new HashMap<String,String>(0); } //類方法註解 @TestA(name="protected method",id=4,gid=Long.class) protected void b(){ Map<String,String> m = new HashMap<String,String>(0); } //類方法註解 @TestA(name="private method",id=5,gid=Long.class) private void c(){ Map<String,String> m = new HashMap<String,String>(0); } public void b(Integer a){ } }
(1) 運行時 Annotation 指 @Retention 爲 RUNTIME 的 Annotation,可手動調用下面經常使用 API 解析
method.getAnnotation(AnnotationName.class); method.getAnnotations(); method.isAnnotationPresent(AnnotationName.class);
其餘 @Target 如 Field,Class 方法相似
/* * 根據註解類型返回方法的指定類型註解 */ MethodInfo annotation = (MethodInfo) constructor .getAnnotation(MethodInfo.class);
Annotation[] annotations = clazz.getAnnotations(); for (Annotation annotation : annotations) { MethodInfo methodInfo = (MethodInfo) annotation }
/* * 判斷構造方法中是否有指定註解類型的註解 */ boolean hasAnnotation = constructor .isAnnotationPresent(MethodInfo.class); if (hasAnnotation) { /* * 根據註解類型返回方法的指定類型註解 */ MethodInfo annotation = (MethodInfo) constructor .getAnnotation(MethodInfo.class); }
public class ParseAnnotation { static String className="com.xujun.animation.test.UserAnnotation"; /** * 簡單打印出UserAnnotation 類中所使用到的類註解 該方法只打印了 Type 類型的註解 * * @throws ClassNotFoundException */ public static void parseTypeAnnotation() throws ClassNotFoundException { Class clazz = Class.forName(className); Annotation[] annotations = clazz.getAnnotations(); for (Annotation annotation : annotations) { MethodInfo testA = (MethodInfo) annotation; System.out.println("id= \"" + testA.id() + "\"; name= \"" + testA.name() + "\"; gid = " + testA.gid()); } } /** * 簡單打印出UserAnnotation 類中所使用到的方法註解 該方法只打印了 Method 類型的註解 * * @throws ClassNotFoundException */ public static void parseMethodAnnotation() { Method[] methods = UserAnnotation.class.getDeclaredMethods(); for (Method method : methods) { /* * 判斷方法中是否有指定註解類型的註解 */ boolean hasAnnotation = method.isAnnotationPresent(MethodInfo.class); if (hasAnnotation) { /* * 根據註解類型返回方法的指定類型註解 */ MethodInfo annotation = method.getAnnotation(MethodInfo.class); System.out.println("method = " + method.getName() + " ; id = " + annotation.id() + " ; description = " + annotation.name() + "; gid= " + annotation.gid()); } } } /** * 簡單打印出UserAnnotation 類中所使用到的方法註解 該方法只打印了 Method 類型的註解 * * @throws ClassNotFoundException */ public static void parseConstructAnnotation() { Constructor[] constructors = UserAnnotation.class.getConstructors(); for (Constructor constructor : constructors) { /* * 判斷構造方法中是否有指定註解類型的註解 */ boolean hasAnnotation = constructor .isAnnotationPresent(MethodInfo.class); if (hasAnnotation) { /* * 根據註解類型返回方法的指定類型註解 */ MethodInfo annotation = (MethodInfo) constructor .getAnnotation(MethodInfo.class); System.out.println("constructor = " + constructor.getName() + " ; id = " + annotation.id() + " ; description = " + annotation.name() + "; gid= " + annotation.gid()); } } } public static void main(String[] args) throws ClassNotFoundException { parseTypeAnnotation(); parseMethodAnnotation(); parseConstructAnnotation(); } }
運行以上測試程序,將能夠看到如下輸出結果
id= "0"; name= "type"; gid = class java.lang.Long
method = c ; id = 5 ; description = private method; gid= class java.lang.Long
method = b ; id = 4 ; description = protected method; gid= class java.lang.Long
method = a ; id = 3 ; description = public method; gid= class java.lang.Long
constructor = com.xujun.animationdemo.UserAnnotation ; id = 2 ; description = construct; gid= class java.lang.Long
轉載請註明原博客地址:
掃一掃,歡迎關注個人微信公衆號 stormjun94(徐公碼字), 目前是一名程序員,不只分享 Android開發相關知識,同時還分享技術人成長曆程,包括我的總結,職場經驗,面試經驗等,但願能讓你少走一點彎路。