Java Annotation是JDK5.0引入的一種註釋機制。它與註釋有必定區別,能夠理解爲代碼上的特殊標記,經過這些標記咱們能夠在編譯,類加載,運行等程序類的生命週期內被讀取、執行相應的處理。經過註解開發人員能夠在不改變原有代碼和邏輯的狀況下在源代碼中嵌入補充信息。java
咱們能夠這樣理解這張圖:架構
(1)Annotation是個接口,它有RetentionPolicy和ElementType屬性ide
(2)一個Annotation接口和一個RetentionPolicy相關聯,和1~n個ElementType相關聯對象
(3)右半邊的Override、Target等都是java中自帶的Annotation的實現類blog
RetentionPolicy和ElementType是Annotation重要的組成部分。繼承
一、RetentionPolicy是Enum枚舉類型,它用來指定Annotation的策略。通俗點說,就是不一樣RetentionPolicy類型的Annotation的做用域不一樣。
「每1個Annotation」 都與 「1個RetentionPolicy」關聯。
a) 若RetentionPolicy的類型爲 SOURCE,則意味着:Annotation僅存在於編譯器處理期間,編譯器處理完以後,該Annotation就沒用了。
例如,「 @Override 」標誌就是一個策略爲SOURCE的Annotation。當它修飾一個方法的時候,就意味着該方法覆蓋父類的方法;而且在編譯期間會進行語法檢查!編譯器處理完後,「@Override」就沒有任何做用了。
b) 若RetentionPolicy的類型爲 CLASS,則意味着:編譯器將Annotation存儲於類對應的.class文件中,它是Annotation的默認行爲。
c) 若RetentionPolicy的類型爲 RUNTIME,則意味着:編譯器將Annotation存儲於class文件中,而且可由JVM讀入。接口
二、 ElementType 是Enum枚舉類型,它用來指定Annotation的類型。
「每1個Annotation」 都與 「1~n個ElementType」關聯。當Annotation與某個ElementType關聯時,就意味着:Annotation有了某種用途。
例如,若一個Annotation對象是METHOD類型,則該Annotation只能用來修飾方法。生命週期
Annotation的通用定義:作用域
@Documented @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface MyFirstAnnotation { }
這段代碼定義了一個Annotation,它的名字是MyFirstAnnotation。定義以後,咱們就能夠在代碼中使用「@MyFirstAnnotation」來調用它。開發
而其它的@Documented, @Target, @Retention, @interface都是來修飾MyFirstAnnotation的。它們的含義以下:
(1) @interface
使用@interface定義註解時,意味着它實現了java.lang.annotation.Annotation接口,即該註解就是一個Annotation。
定義Annotation時,@interface是必須的。
注意:它和咱們一般的implemented實現接口的方法不一樣。Annotation接口的實現細節都由編譯器完成。經過@interface定義註解後,該註解不能繼承其餘的註解或接口。
(2)@Documented
類和方法的Annotation在缺省狀況下是不出如今javadoc中的。若是使用@Documented修飾該Annotation,則表示它能夠出如今javadoc中。
定義Annotation時,@Documented無關緊要;若沒有定義,則Annotation不會出如今javadoc中。
(3)@Target(ElementType.TYPE)
前面咱們說過,ElementType 是Annotation的類型屬性。而@Target的做用,就是來指定Annotation的類型屬性。
@Target(ElementType.TYPE) 的意思就是指定該Annotation的類型是ElementType.TYPE。這就意味着,MyFirstAnnotation是來修飾「類、接口(包括註釋類型)或枚舉聲明」的註解。
定義Annotation時,@Target無關緊要。如有@Target,則該Annotation只能用於它所指定的地方;若沒有@Target,則該Annotation能夠用於任何地方。.
(4)@Retention(RetentionPolicy.RUNTIME)
前面咱們說過,RetentionPolicy 是Annotation的策略屬性,而@Retention的做用,就是指定Annotation的策略屬性。
@Retention(RetentionPolicy.RUNTIME) 的意思就是指定該Annotation的策略是RetentionPolicy.RUNTIME。這就意味着,編譯器會將該Annotation信息保留在.class文件中,而且能被虛擬機讀取。
定義Annotation時,@Retention無關緊要。若沒有@Retention,則默認是RetentionPolicy.CLASS。
也就是Annotation架構圖中的右半邊:
因爲「@Deprecated和@Override」相似,「@Documented, @Retention, @Target」在上文已經作過解釋;下面,咱們對@Deprecated, @Inherited, @SuppressWarnings 這3個Annotation進行說明。
@Documented @Retention(RetentionPolicy.RUNTIME) public @interface Deprecated { }
說明:
(1) @interface -- 它的用來修飾Deprecated,意味着Deprecated實現了java.lang.annotation.Annotation接口;即Deprecated就是一個註解。
(2) @Documented -- 它的做用是說明該註解能出如今javadoc中。
(3) @Retention(RetentionPolicy.RUNTIME) -- 它的做用是指定Deprecated的策略是RetentionPolicy.RUNTIME。這就意味着,編譯器會將Deprecated的信息保留在.class文件中,而且能被虛擬機讀取。
(4) @Deprecated 所標註內容,再也不被建議使用。
例如,若某個方法被 @Deprecated 標註,則該方法再也不被建議使用。若是有開發人員試圖使用或重寫被@Deprecated標示的方法,編譯器會給相應的提示信息。
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Inherited { }
說明:
(1) @interface -- 它的用來修飾Inherited,意味着Inherited實現了java.lang.annotation.Annotation接口;即Inherited就是一個註解。
(2) @Documented -- 它的做用是說明該註解能出如今javadoc中。
(3) @Retention(RetentionPolicy.RUNTIME) -- 它的做用是指定Inherited的策略是RetentionPolicy.RUNTIME。這就意味着,編譯器會將Inherited的信息保留在.class文件中,而且能被虛擬機讀取。
(4) @Target(ElementType.ANNOTATION_TYPE) -- 它的做用是指定Inherited的類型是ANNOTATION_TYPE。這就意味着,@Inherited只能被用來標註「Annotation類型」。
(5) @Inherited 的含義是,它所標註的Annotation將具備繼承性。
假設,咱們定義了某個Annotaion,它的名稱是MyAnnotation,而且MyAnnotation被標註爲@Inherited。如今,某個類Base使用了MyAnnotation,則Base具備了「具備了註解MyAnnotation」;如今,Sub繼承了Base,因爲MyAnnotation是@Inherited的(具備繼承性),因此,Sub也「具備了註解MyAnnotation」。
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) @Retention(RetentionPolicy.SOURCE) public @interface SuppressWarnings { String[] value(); }
說明:
(01) @interface -- 它的用來修飾SuppressWarnings,意味着SuppressWarnings實現了java.lang.annotation.Annotation接口;即SuppressWarnings就是一個註解。 (02) @Retention(RetentionPolicy.SOURCE) -- 它的做用是指定SuppressWarnings的策略是RetentionPolicy.SOURCE。這就意味着,SuppressWarnings信息僅存在於編譯器處理期間,編譯器處理完以後SuppressWarnings就沒有做用了。 (03) @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) -- 它的做用是指定SuppressWarnings的類型同時包括TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE。 TYPE意味着,它能標註「類、接口(包括註釋類型)或枚舉聲明」。 FIELD意味着,它能標註「字段聲明」。 METHOD意味着,它能標註「方法」。 PARAMETER意味着,它能標註「參數」。 CONSTRUCTOR意味着,它能標註「構造方法」。 LOCAL_VARIABLE意味着,它能標註「局部變量」。 (04) String[] value(); 意味着,SuppressWarnings能指定參數 (05) SuppressWarnings 的做用是,讓編譯器對「它所標註的內容」的某些警告保持靜默。例如,"@SuppressWarnings(value={"deprecation", "unchecked"})" 表示對「它所標註的內容」中的 「SuppressWarnings再也不建議使用警告」和「未檢查的轉換時的警告」保持沉默。