天天看點

Java自定義注解 Annotation

Java注解是附加在代碼中的元資訊,用于一些工具在編譯、運作時進行解析和使用,起到說明、配置的功能。注解不會也不能影響代碼的實際邏輯,僅僅起到輔助作用。

元注解:

元注解的作用是負責注解其他注解。

@Target:說明Annotation所修飾的對象範圍,Annotation可被用于packages/、types(類、接口、枚舉、Annotation類型)、類型成員(方法、構造方法、成員變量、枚舉值)、方法參數和本地變量(如循環變量、catch參數)。在Annotation類型的聲明中使用target可更加明确其修飾的目标。

constructor:描述構造器

Field:描述域

Local_variable:描述局部變量

Method:描述方法

Package:描述包

Parameter:描述參數

Type:描述類、接口(包括注解類型)、enum聲明

@Retention 定義該Annotation被保留的時間長短;某些Annotation 僅出現在源代碼中,而被編譯器丢棄;另一些被編譯在class檔案中;編譯在class檔案中的Annotation會被虛拟機忽略,另一些在class裝載時被讀取(Annotation與class在使用上是被分離的,互不影響)。

source:源檔案中有效

class:class檔案中有效

runtime:運作時有效

@Documented:用于描述其他類型的Annotation應該被作為被标注的程式成員的公共API,是以可以被例如javadoc類的工具文檔化。是一個标記注解,沒有成員。

@Inherited 元注解是一個标記注解,闡述了某個被标注的類型是被繼承的。如果使用一個@Inherited 修飾的Annotation 類型被用于一個class,則這個 Annotation 将被用于該class的子類。@Inherited annotation 類型是被标注過的class的子類所繼承。類并不從他所實作的接口繼承 annotation ,方法并不從它所重載的方法繼承annotation。

當@inherited annotation 類型标注的 annotation 的retention 是 runtime ,則反射api 增強了這種繼承性。如果我們使用java.lang.reflect 去查詢一個@inherited annotation 類型的 annotation 時,反射代碼檢查将展開工作:檢查class 和起父類,直到發現制定的 annotation 類型,或者到達類繼承結構的頂層。

自定義注解:

使用@interface 自定義注解時,自動繼承 java.lang.annotation.Annotation 接口,由編譯程式自動完成其他細節。在定義注解時,不能繼承其他的注解或接口。@interface用來聲明一個注解,其中的每一個方法實際上是聲明了一個配置參數。方法的名稱就是參數的名稱,傳回值的類型就是參數的類型(傳回值類型隻能是基本類型、class、String、enum)。可以通過default 來聲明參數的預設值。

public @interface 注解名{定義體}

所有基本資料類型(int、float、boolean、byte、double、char、long、short)

String類型

Class類型

enum類型

Annotation類型

以上所有類型的數組

Annotation類型的參數設定:

1、隻能用public 或預設 default 兩個通路權修飾符,例如String value();這裡為default 預設類型

2、參數成員隻能用基本類型 byte short char int long float double boolean八種基本資料類型和String enum class annotation 等資料類型,以及這些類型的數組。

3、如果隻有一個參數成員,最好把參數名稱設為 value 加小括号。

注解元素的預設值:

注解元素必須有确定的值,要麼在定義注解的預設值中指定,要麼在使用注解時指定,非基本類型的注解元素的值不可為null。是以,使用空字元串或0作為預設值是一種常用的做法。這個限制使得處理器很難表現一個元素的存在或缺失的狀态,因為每個注解的聲明中,所有元素都存在,并且都具有相應的值,為了繞開這個限制,我們隻能定義一些特殊的值,例如空字元串或者負數,一次表示某個元素不存在,是定義注解時的習慣用法。