天天看點

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

JAVA:淺談自定義注解