JAVA:淺談自定義註解

Java 註解(Annotation)又稱 Java 標註,是 JDK5.0 引入的一種註釋機制。
Java 語言中的類、方法、變量、參數和包等都可以被標註。和 Javadoc 不同,Java 標註可以通過反射獲取標註內容。在編譯器生成類文件時,標註可以被嵌入到字節碼中。Java 虛擬機可以保留標註內容,在運行時可以獲取到標註內容 。 當然它也支持自定義 Java 標註。
自定義註解:

1.自定義註解需要使用 @interface 來開發,類似於開發一個接口

//聲明一個名字爲Note的註解
public @interface Note {
}

2.自定義註解,需要使用元註解來聲明自定義註解的特性

2.1 @Target

用來聲明註解可以放在什麼位置,如果不寫,則可以用在任何位置
ElementType.ANNOTATION_TYPE:———用在註解
ElementType.CONSTRUCTOR:—————用在構造函數
ElementType.FIELD:—————————字段、枚舉的常量
ElementType.LOCAL_VARIABLE:———局部變量
ElementType.METHOD ———————方法
ElementType.PACKA————————包
ElementType.PARAMETER:————方法參數
ElementType.TYPE: ———————接口、類、枚舉、註解

/*聲明一個只能在方法前使用的註解*/
@Target({ElementType.METHOD})
@interface Note {
}

2.2 @Retention 用來聲明被修飾的註解會被保留到什麼階段

可以在該註解的屬性中,通過RetentionPolicy類型的值來指定註解被保留到何時。
a.RetentionPolicy.SOURCE
此註解會保留到源碼階段(.java文件)中在編譯過程中被刪除。
這種類型的註解通常是爲了在編譯時給出提示。
b.RetentionPolicy.CLASS
此註解將會被保留到源碼階段和編譯階段(.java文件和.class文件)中,在類加載過程中被刪除。
這種類型的註解通常是爲了提供給類加載器用。
c.RetentionPolicy.RUNTIME
此類註解會被保留在源碼階段(.java文件)、編譯階段(.class文件)、運行階段(內存中的字節碼)中。
這種類型的註解通常用來運行時提供程序的控制,一般用於反射機制控制程序的運行過程。
也只有RUNTIME級別的註解才能通過反射技術完成反射相關的操作,Spring框架大量使用了該技術

//定義一個可以用於反射的註解
@Retention(RetentionPolicy.RUNTIME)
@interface Note {
}

2.3 @Documented

用來聲明被修飾的註解是否要被文檔提取工具提取當文檔中。
默認情況下,javadoc是不包括註解的. 但如果聲明註解時指定了@Documented,則它會被 javadoc 之類的工具處理

//當使用javadoc命令生成可讀文檔的時候,該註解會出現在文檔中
@Documented
@interface Note {
}

2.4 @Inherited被修飾的註解具有繼承性

默認沒有繼承性,當使用了該標籤之後,被註解標記的類將自動繼承該註解中的方法。
由於要繼承,所以要使用@Inherited修飾前,需要使用@Retention(RetentionPolicy.RUNTIME)修飾,只有這樣文件才能完成反射傳值,如果不使用反射傳值,則不需要@Retention(RetentionPolicy.RUNTIME)修飾

//定義一個可以被反射註解
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface InheritedTest {
    String value();
}

使用上面自定義的註解修飾一個新的類,並且通過註解爲新的類添加說明

@InheritedTest(value = "Ben從註解中獲得的值")
public class Ben {
}

由於被@Inherited被修飾的註解是否具有繼承性,所以Ben的子類也會有Ben的說明

//BenSong這個類繼承了Ben類,那麼BenSon中就應該含有Ben從註解中獲得的值
public class BenSon extends Ben{
}

測試一下繼承屬性是否存在,這裏用了反射方式

    public static void main(String[] args) {
        Class<BenSon> benSonClass = BenSon.class;
        //判斷BenSon是否繼承了Ben類中的註解
        if (benSonClass.isAnnotationPresent(InheritedTest.class)){
            //如果繼承了註解,則輸出註解中的類容。
            System.out.println(benSonClass.getAnnotation(InheritedTest.class).value());
        }
    }

得到的結果:成功輸出了父類Ben中的值,得到結論@Inherited被修飾的註解具有繼承性
在這裏插入圖片描述

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