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被修飾的注解具有繼承性
