註解解析

參考該文章:http://www.cnblogs.com/mouseIT/p/5033746.html
作者補充了註解解析

註解格式

@Documented
@Inherited
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
//定義註解類
public @interface Book{
    //定義Book的書名
    String bookname();
    //定義Book的價格,默認99.9
    Double price() default 99.9;
    //定義作者數組,其中
    String[] authors();
}

詳解

元註解

  • @Target 註釋的使用位置.
  • @Retention 註解的聲明週期.
  • @Documented
  • @Inherited 被該註解標記類的,子類都繼承該註解

@Target

  • 作用:指明此註解用在哪個位置,如果不寫默認是任何地方都可以使用。
    • 可選的參數值在枚舉類ElemenetType中包括:
 TYPE: 用在類,接口上
 FIELD:用在成員變量上
 METHOD: 用在方法上
 PARAMETER:用在參數上
 CONSTRUCTOR:用在構造方法上
 LOCAL_VARIABLE:用在局部變量上
 

@Retention

  • 作用:定義該註解的生命週期(有效範圍)。
    • 可選的參數值在枚舉類型RetentionPolicy中包括
SOURCE:註解只存在於Java源代碼中,編譯生成的字節碼文件中就不存在了。
CLASS:註解存在於Java源代碼、編譯以後的字節碼文件中,運行的時候內存中沒有,默認值。
RUNTIME:註解存在於Java源代碼中、編譯以後的字節碼文件中、運行時內存中,程序可以通過反射獲取該註解。【常用】

@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類型被發現,或者到達類繼承結構的頂層。

@Documented:

該屬性用於描述其它類型的annotation應該被作爲被標註的程序成員的公共API,因此可以被例如javadoc此類的工具文檔化。Documented是一個標記註解,沒有成員。

註解類的成員屬性

註解參數的可支持數據類型:

  • 1.所有基本數據類型(int,float,boolean,byte,double,char,long,short)
  • 2.String類型
  • 3.Class類型
  • 4.enum類型
  • 5.Annotation類型
  • 6.以上所有類型的數組

Annotation類型裏面的參數該怎麼設定:

第一,只能用public或默認(default)這兩個訪問權修飾.例如,String value();這裏把方法設爲defaul默認類型;

第二,參數成員只能用基本類型byte,short,char,int,long,float,double,boolean八種基本數據類型和String,Enum,Class,annotations等數據類型,以及這一些類型的數組.例如,String value();這裏的參數成員就爲String;

第三,如果只有一個參數成員,最好把參數名稱設爲"value",後加小括號.例:下面的例子FruitName註解就只有一個參數成員。

對註解的解析

  • 在對註解類進行確定之後,便是解析註解

原理

通過反射,拿到註解類的class字節碼文件,再獲取到註解類的屬性

  • 什麼是註解解析

  • 通過Java技術獲取註解數據的過程則稱爲註解解析。

與註解解析相關的接口

Anontation:所有註解類型的公共接口,類似所有類的父類是Object。

AnnotatedElement:定義了與註解解析相關的方法,常用方法:

boolean isAnnotationPresent(Class annotationClass); 判斷當前對象是否有指定的註解,有則返回true,否則返回false。

T getAnnotation(Class annotationClass); 獲得當前對象上指定的註解對象。

3.5.3 獲取註解數據的原理

  • 註解作用在那個成員上,就通過反射獲得該成員的對象(Filed)來得到它的註解。

  • 如註解作用在方法上,就通過方法(Method)對象得到它的註解*

  • 如註解作用在類上,就通過Class對象得到它的註解

//對類進行註解  ElementType.TYPE
@Book(value = "西遊記1", price=9988, authors = {"吳承恩1", "白求恩1"})
public class BookShelf {

    private int id;
    
    //對方法進行註解  ElementType.METHOD
    @Book(value = "西遊記", price = 998, authors = {"吳承恩", "白求恩"})
    public void show() {
        //定義變量
        String value = "";
        int price = 0;
        String[] authors = {};

        //獲取當前類的Class對象
        Class<? extends BookShelf> cls = this.getClass();
        try {
            //獲取當前方法對象
            Method show = cls.getMethod("show");
            //判斷當前方法上是否有註解
            if (show.isAnnotationPresent(Book.class)) {
                Book book = show.getAnnotation(Book.class);
                value = book.value();
                price = book.price();
                authors = book.authors();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("書名爲 : " + value);
        System.out.println("價格爲 : " + price);
        System.out.println("作者爲 : " + Arrays.toString(authors));
    }
}

Test1

class Test1 {
    public static void main(String[] args) {
        BookShelf bookShelf = new BookShelf();
        bookShelf.show();
    }
}

Test2

public class Test2 {
    public static void main(String[] args) throws ClassNotFoundException {
        Class<?> cls = Class.forName("DataSource.BookShelf");
        if(cls.isAnnotationPresent(Book.class)){
            Book book = cls.getAnnotation(Book.class);
            String value = book.value();
            int price = book.price();
            String[] authors = book.authors();
            System.out.println("value = " + value);
            System.out.println("price = " + price);
            System.out.println("authors = " + Arrays.toString(authors));
        }
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章