Annotation 深度剖析(一)
一. Annotation 介面(interface) 所有 annotation 型別 都要擴充套件的公共介面。
二. 列舉型別
1. ElementType 程式元素型別 列舉類 通常是與 @target 元註釋型別一起使用,指定什麼情況使用註釋是合法的
public enum ElementType
extends Enum<ElementType>
列舉常量
(a). ANNOTATION_TYPE //註釋型別宣告
(b).CONSTRUCTOR //構造方法宣告
(c).LOCAL_VARIABLE //區域性變數宣告
(d).PACKAGE //包宣告
(e).PARAMETER //引數型別宣告
(d).TYPE //型別,介面(包括註釋型別)或者列舉宣告
2.RetentionPolicy enum 列舉類 (儲存策略)
(a).SOURCE 編譯器要丟棄的註釋 ,即儲存在原始碼期間,javadoc 後會被丟棄
(b).CLASS 編譯器將把註釋記錄在類檔案中,但在執行時 VM 不需要保留註釋。這是預設的行為。
(c). RUNTIME 編譯器將把註釋記錄在類檔案中,在執行時 VM 將保留註釋,因此可以反射性地讀取。
三 註釋型別
(a).Documented 指示某一型別的註釋將通過 javadoc 和類似的預設工具進行文件化。應使用此型別來註釋這些文件的宣告:其註釋會影響由其客戶端註釋的元素的使用。如果型別宣告是用Documented 來註釋的,則其註釋將成為註釋元素的公共API 的一部分。 (根據這段話的意識來理解,@Document 如果標記了@Document 來註解,如果匯出Api 文件的話,會把註解的 轉為 註解 的API) 原始碼如下:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Documented { }
(b).Inherited 指示註釋型別會被自動繼承指示註釋型別被自動繼承。如果在註釋型別宣告中存在 Inherited 元註釋,並且使用者在某一類宣告中查詢該註釋型別,同時該類宣告中沒有此型別的註釋,則將在該類的超類中自動查詢該註釋型別。此過程會重複進行,直到找到此型別的註釋或到達了該類層次結構的頂層 (Object) 為止。如果沒有超類具有該型別的註釋,則查詢將指示當前類沒有這樣的註釋。(如果一個使用了@Inherited修飾的annotation型別被用於一個class,則這個annotation將被用於該class的子類。可以理解有穿透性)原始碼如下:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Inherited { }
(c).Retention 指示註釋型別的註釋要保留多久。如果註釋型別宣告中不存在 Retention 註釋,則保留策略預設為 RetentionPolicy.CLASS。只有元註釋型別直接用於註釋時,Target 元註釋才有效。如果元註釋型別用作另一種註釋型別的成員,則無效。(指註釋儲存時間,分為三種 :原始碼,執行中,編譯後)
四。註解
(a).AnnotationTypeMismatchException 若某個註釋的型別在對該註釋進行編譯(或序列化)後發生了更改,而程式試圖訪問該註釋的元素時,丟擲此異常。(執行時異常) 原始碼如下:
public class AnnotationTypeMismatchException extends RuntimeException { private static final long serialVersionUID = 8125925355765570191L; /** * The <tt>Method</tt> object for the annotation element. */ private final Method element; /** * The (erroneous) type of data found in the annotation. This string * may, but is not required to, contain the value as well. The exact * format of the string is unspecified. */ private final String foundType; /** * Constructs an AnnotationTypeMismatchException for the specified * annotation type element and found data type. * * @param element the <tt>Method</tt> object for the annotation element * @param foundType the (erroneous) type of data found in the annotation. * This string may, but is not required to, contain the value * as well. The exact format of the string is unspecified. */ public AnnotationTypeMismatchException(Method element, String foundType) { super("Incorrectly typed data found for annotation element " + element + " (Found data of type " + foundType + ")"); this.element = element; this.foundType = foundType; } /** * Returns the <tt>Method</tt> object for the incorrectly typed element. * * @return the <tt>Method</tt> object for the incorrectly typed element */ public Method element() { return this.element; } /** * Returns the type of data found in the incorrectly typed element. * The returned string may, but is not required to, contain the value * as well. The exact format of the string is unspecified. * * @return the type of data found in the incorrectly typed element */ public String foundType() { return this.foundType; } }
(b).IncompleteAnnotationException 若某個註釋在編譯(或序列化)後將某個註釋型別新增到其型別定義中,而程式試圖該註釋型別的元素時,丟擲此異常。如果新元素有預設值,則不丟擲此異常。原始碼如下
public class IncompleteAnnotationException extends RuntimeException { private static final long serialVersionUID = 8445097402741811912L; private Class<? extends Annotation> annotationType; private String elementName; /** * Constructs an IncompleteAnnotationException to indicate that * the named element was missing from the specified annotation type. * * @param annotationType the Class object for the annotation type * @param elementName the name of the missing element * @throws NullPointerException if either parameter is {@code null} */ public IncompleteAnnotationException( Class<? extends Annotation> annotationType, String elementName) { super(annotationType.getName() + " missing element " + elementName.toString()); this.annotationType = annotationType; this.elementName = elementName; } /** * Returns the Class object for the annotation type with the * missing element. * * @return the Class object for the annotation type with the * missing element */ public Class<? extends Annotation> annotationType() { return annotationType; } /** * Returns the name of the missing element. * * @return the name of the missing element */ public String elementName() { return elementName; } }
(c).AnnotationFormatError 錯誤
構造一個指示指定註釋型別中缺少指定元素的 IncompleteAnnotationException。
引數:
annotationType
- 註釋型別的 Class 物件
elementName
- 缺少元素的名稱