一、什麼是註解
註解也叫元資料,例如我們常見的@Override和@Deprecated,註解是JDK1.5版本開始引入的一個特性,
用於對程式碼進行說明,可以對包、類、介面、欄位、方法引數、區域性變數等進行註解。
一般常用的註解可以分為三類:
1、Java自帶的標準註解,包括@Override(標明重寫某個方法)、@Deprecated(標明某個類或方法過時)和@SuppressWarnings(標明要忽略的警告),使用這些註解後編譯器就會進行檢查。
2、類為元註解,元註解是用於定義註解的註解,包括@Retention(標明註解被保留的階段)、@Target(標明註解使用的範圍)、@Inherited(標明註解可繼承)、@Documented(標明是否生成javadoc文件)
3、類為自定義註解,可以根據自己的需求定義註解
二、註解的用途
在看註解的用途之前,有必要簡單的介紹下XML和註解區別,
註解:是一種分散式的元資料,與原始碼緊繫結。
xml:是一種集中式的元資料,與原始碼無繫結
生成文件,透過程式碼裡標識的元資料生成javadoc文件。
編譯檢查,透過程式碼裡標識的元資料讓編譯器在編譯期間進行檢查驗證。
編譯時動態處理,編譯時透過程式碼裡標識的元資料動態處理,例如動態生成程式碼。
執行時動態處理,執行時透過程式碼裡標識的元資料動態處理,例如使用反射注入例項
三、註解的實現原理
實現註解三要素:
1、註解宣告
2、使用註解的元素
3、操作註解使其起作用(註解處理器)
註解宣告
首先我們讓看一下java中的元註解(也就是上面提到的註解的註解),總共有4個如下:
@Target,@Retention,@Documented,@Inherited這4個元註解都是在jdk的java.lang.annotation包下面,
@Target:Target說明的是Annotation所修飾的物件範圍。@Retention:
定義了該Annotation被保留的時間長短:某些Annotation僅出現在原始碼中,而被編譯器丟棄;而另一些卻被編譯在class檔案中;編譯在class檔案中的Annotation可能會被虛擬機器忽略,
而另一些在class被裝載時將被讀取(請注意並不影響class的執行,因為Annotation與class在使用上是被分離的)。
使用這個元註解可以對 Annotation的“生命週期”限制。@Documented:@Documented用於描述其它型別的annotation應該被作為被標註的程式成員的公共API,因此可以被例如javadoc此類的工具文件化。Documented是一個標記註解,沒有成員
@Inherited:@Inherited 元註解是一個標記註解,@Inherited闡述了某個被標註的型別是被繼承的。如果一個使用了@Inherited修飾的annotation型別被用於一個class,
則這個annotation將被用於該class的子類。
注意:@Inherited annotation型別是被標註過的class的子類所繼承。類並不從它所實現的介面繼承annotation,方法並不從它所過載的方法繼承annotation。
當@Inherited annotation型別標註的annotation的Retention是RetentionPolicy.RUNTIME,則反射API增強了這種繼承性。如果我們使用java.lang.reflect去查詢一個@Inherited annotation型別的annotation時,
反射程式碼檢查將展開工作:檢查class和其父類,直到發現指定的annotation型別被發現,或者到達類繼承結構的頂層。
java.lang.reflect.AnnotatedElement 介面是所有程式元素(Class、Method和Constructor)的父介面,所以程式透過反射獲取了某個類的AnnotatedElement物件之後,程式就可以呼叫該物件的如下四個個方法來訪問Annotation資訊:
方法1:<T extends Annotation> T getAnnotation(Class<T> annotationClass): 返回改程式元素上存在的、指定型別的註解,如果該型別註解不存在,則返回null。
方法2:Annotation[] getAnnotations():返回該程式元素上存在的所有註解。
方法3:boolean is AnnotationPresent(Class<?extends Annotation> annotationClass):判斷該程式元素上是否
一、什麼是註解
註解也叫元資料,例如我們常見的@Override和@Deprecated,註解是JDK1.5版本開始引入的一個特性,
用於對程式碼進行說明,可以對包、類、介面、欄位、方法引數、區域性變數等進行註解。
一般常用的註解可以分為三類:
1、Java自帶的標準註解,包括@Override(標明重寫某個方法)、@Deprecated(標明某個類或方法過時)和@SuppressWarnings(標明要忽略的警告),使用這些註解後編譯器就會進行檢查。
2、類為元註解,元註解是用於定義註解的註解,包括@Retention(標明註解被保留的階段)、@Target(標明註解使用的範圍)、@Inherited(標明註解可繼承)、@Documented(標明是否生成javadoc文件)
3、類為自定義註解,可以根據自己的需求定義註解
二、註解的用途
在看註解的用途之前,有必要簡單的介紹下XML和註解區別,
註解:是一種分散式的元資料,與原始碼緊繫結。
xml:是一種集中式的元資料,與原始碼無繫結
生成文件,透過程式碼裡標識的元資料生成javadoc文件。
編譯檢查,透過程式碼裡標識的元資料讓編譯器在編譯期間進行檢查驗證。
編譯時動態處理,編譯時透過程式碼裡標識的元資料動態處理,例如動態生成程式碼。
執行時動態處理,執行時透過程式碼裡標識的元資料動態處理,例如使用反射注入例項
三、註解的實現原理
實現註解三要素:
1、註解宣告
2、使用註解的元素
3、操作註解使其起作用(註解處理器)
註解宣告
首先我們讓看一下java中的元註解(也就是上面提到的註解的註解),總共有4個如下:
@Target,@Retention,@Documented,@Inherited這4個元註解都是在jdk的java.lang.annotation包下面,
@Target:Target說明的是Annotation所修飾的物件範圍。@Retention:
定義了該Annotation被保留的時間長短:某些Annotation僅出現在原始碼中,而被編譯器丟棄;而另一些卻被編譯在class檔案中;編譯在class檔案中的Annotation可能會被虛擬機器忽略,
而另一些在class被裝載時將被讀取(請注意並不影響class的執行,因為Annotation與class在使用上是被分離的)。
使用這個元註解可以對 Annotation的“生命週期”限制。@Documented:@Documented用於描述其它型別的annotation應該被作為被標註的程式成員的公共API,因此可以被例如javadoc此類的工具文件化。Documented是一個標記註解,沒有成員
@Inherited:@Inherited 元註解是一個標記註解,@Inherited闡述了某個被標註的型別是被繼承的。如果一個使用了@Inherited修飾的annotation型別被用於一個class,
則這個annotation將被用於該class的子類。
注意:@Inherited annotation型別是被標註過的class的子類所繼承。類並不從它所實現的介面繼承annotation,方法並不從它所過載的方法繼承annotation。
當@Inherited annotation型別標註的annotation的Retention是RetentionPolicy.RUNTIME,則反射API增強了這種繼承性。如果我們使用java.lang.reflect去查詢一個@Inherited annotation型別的annotation時,
反射程式碼檢查將展開工作:檢查class和其父類,直到發現指定的annotation型別被發現,或者到達類繼承結構的頂層。
java.lang.reflect.AnnotatedElement 介面是所有程式元素(Class、Method和Constructor)的父介面,所以程式透過反射獲取了某個類的AnnotatedElement物件之後,程式就可以呼叫該物件的如下四個個方法來訪問Annotation資訊:
方法1:<T extends Annotation> T getAnnotation(Class<T> annotationClass): 返回改程式元素上存在的、指定型別的註解,如果該型別註解不存在,則返回null。
方法2:Annotation[] getAnnotations():返回該程式元素上存在的所有註解。
方法3:boolean is AnnotationPresent(Class<?extends Annotation> annotationClass):判斷該程式元素上是否