Java Annotation使用詳解
Java Annotation是JDK5.0引入的一種註釋機制。它與註釋有一定區別,可以理解為代碼上的特殊標記,通過這些標記我們可以在編譯,類加載,運行等程序類的生命周期內被讀取、執行相應的處理。通過註解開發人員可以在不改變原有代碼和邏輯的情況下在源代碼中嵌入補充信息。
一、Annotation架構圖
我們可以這樣理解這張圖:
(1)Annotation是個接口,它有RetentionPolicy和ElementType屬性
(2)一個Annotation接口和一個RetentionPolicy相關聯,和1~n個ElementType相關聯
(3)右半邊的Override、Target等都是java中自帶的Annotation的實現類
二、RetentionPolicy和ElementType
RetentionPolicy和ElementType是Annotation重要的組成部分。
1、RetentionPolicy是Enum枚舉類型,它用來指定Annotation的策略。通俗點說,就是不同RetentionPolicy類型的Annotation的作用域不同。
“每1個Annotation” 都與 “1個RetentionPolicy”關聯。
a) 若Annotation的類型為 SOURCE,則意味著:Annotation僅存在於編譯器處理期間,編譯器處理完之後,該Annotation就沒用了。
b) 若Annotation的類型為 CLASS,則意味著:編譯器將Annotation存儲於類對應的.class文件中,它是Annotation的默認行為。
c) 若Annotation的類型為 RUNTIME,則意味著:編譯器將Annotation存儲於class文件中,並且可由JVM讀入。
2、 ElementType 是Enum枚舉類型,它用來指定Annotation的類型。
“每1個Annotation” 都與 “1~n個ElementType”關聯。當Annotation與某個ElementType關聯時,就意味著:Annotation有了某種用途。
例如,若一個Annotation對象是METHOD類型,則該Annotation只能用來修飾方法。
三、定義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。這就意味著,MyAnnotation1是來修飾“類、接口(包括註釋類型)或枚舉聲明”的註解。
定義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。
四、Java自帶的Annotation
也就是Annotation架構圖中的右半邊:
由於“@Deprecated和@Override”類似,“@Documented, @Retention, @Target”在上文已經做過解釋;下面,我們對@Deprecated, @Inherited, @SuppressWarnings 這3個Annotation進行說明。
1、@Deprecated,定義如下:
@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標示的方法,編譯器會給相應的提示信息。
2、@Inherited,定義如下:
@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”。
3、@SuppressWarnings,定義如下:
@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不再建議使用警告”和“未檢查的轉換時的警告”保持沈默。
Java Annotation使用詳解