Annotation分類

 Annotation 分類

1 標準 Annotation,Override, Deprecated, SuppressWarnings

標準 Annotation 是指 Java 自帶的幾個 Annotation,上面三個分別表示重寫函數,函數已經被禁止使用,忽略某項 Warning

2 元 Annotation,@Retention, @Target, @Inherited, @Documented

元 Annotation 是指用來定義 Annotation 的 Annotation,在後面 Annotation 自定義部分會詳細介紹含義

3 自定義 Annotation

1 定義

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Inherited
public @interface MethodInfo {

    String author() default "[email protected]";

    String date();

    int version() default 1;
}

2 調用

public class App {

    @MethodInfo(
        author = “[email protected]”,
        date = "2014/02/14",
        version = 2)
    public String getAppName() {
        return "trinea";
    }
}

這裏是調用自定義 Annotation——MethodInfo 的示例。
MethodInfo Annotation 作用爲給方法添加相關信息,包括 author、date、version。

自定義 Annotation 表示自己根據需要定義的 Annotation,定義時需要用到上面的元 Annotation
這裏是一種分類而已,也可以根據作用域分爲源碼時、編譯時、運行時 Annotation,後面在自定義 Annotation 時會具體介紹

這裏是 MethodInfo 的實現部分
(1). 通過 @interface 定義,註解名即爲自定義註解名
(2). 註解配置參數名爲註解類的方法名,且:
a. 所有方法沒有方法體,沒有參數沒有修飾符,實際只允許 public & abstract 修飾符,默認爲 public ,不允許拋異常
b. 方法返回值只能是基本類型,String, Class, annotation, enumeration 或者是他們的一維數組
c. 若只有一個默認屬性,可直接用 value() 函數。一個屬性都沒有表示該 Annotation 爲 Mark Annotation
(3). 可以加 default 表示默認值

3 元 Annotation

@Documented 是否會保存到 Javadoc 文檔中

@Retention 保留時間,可選值 SOURCE(源碼時),CLASS(編譯時),RUNTIME(運行時),默認爲 CLASS,SOURCE 大都爲 Mark Annotation,這類 Annotation 大都用來校驗,比如 Override, Deprecated, SuppressWarnings

@Retention: 定義註解的保留策略

    @Retention(RetentionPolicy.SOURCE)//註解僅存在於源碼中,在class字節碼文件中不包含
    @Retention(RetentionPolicy.CLASS)// 默認的保留策略,註解會在class字節碼文件中存在,但運行時無法得
    @Retention(RetentionPolicy.RUNTIME)// 註解會在class字節碼文件中存在,在運行時可以通過反射獲取到

@Target 可以用來修飾哪些程序元素,如 TYPE, METHOD, CONSTRUCTOR, FIELD, PARAMETER 等,未標註則表示可修飾所有

@Target:定義註解的作用目標

其定義的源碼爲: 
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.ANNOTATION_TYPE)
     public @interface Target {
         ElementType[] value();
     }

    @Target(ElementType.TYPE)   //接口、類、枚舉、註解

    @Target(ElementType.FIELD) //字段、枚舉的常量
    @Target(ElementType.METHOD) //方法
    @Target(ElementType.PARAMETER) //方法參數
    @Target(ElementType.CONSTRUCTOR)  //構造函數
    @Target(ElementType.LOCAL_VARIABLE)//局部變量
    @Target(ElementType.ANNOTATION_TYPE)//註解
    @Target(ElementType.PACKAGE) ///包   
其中的@interface是一個關鍵字,在設計annotations的時候必須把一個類型定義爲@interface,而不能用class或interface關鍵字,由以上的源碼可以知道,他的elementType 可以有多個,一個註解可以爲類的,方法的,字段的等等。
@Inherited 是否可以被繼承,默認爲 false

 Annotation 解析

1 運行時 Annotation 解析

(1) 運行時 Annotation 指 @Retention 爲 RUNTIME 的 Annotation,可手動調用下面常用 API 解析

method.getAnnotation(AnnotationName.class);
method.getAnnotations();
method.isAnnotationPresent(AnnotationName.class);
其他 @Target 如 Field,Class 方法類似
getAnnotation(AnnotationName.class) 表示得到該 Target 某個 Annotation 的信息,因爲一個 Target 可以被多個 Annotation 修飾
getAnnotations() 則表示得到該 Target 所有 Annotation
isAnnotationPresent(AnnotationName.class) 表示該 Target 是否被某個 Annotation 修飾
(2) 解析示例如下:
public static void main(String[] args) {
    try {
        Class cls = Class.forName("cn.trinea.java.test.annotation.App");
        for (Method method : cls.getMethods()) {
            MethodInfo methodInfo = method.getAnnotation(
MethodInfo.class);
            if (methodInfo != null) {
                System.out.println("method name:" + method.getName());
                System.out.println("method author:" + methodInfo.author());
                System.out.println("method version:" + methodInfo.version());
                System.out.println("method date:" + methodInfo.date());
            }
        }
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}
以之前自定義的 MethodInfo 爲例,利用 Target(這裏是 Method)getAnnotation 函數得到 Annotation 信息,然後就可以調用 Annotation 的方法得到響應屬性值

發佈了35 篇原創文章 · 獲贊 3 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章