至於關於編譯時的註解,待下篇博客的時候會結合例子講解一下,目前我也正在學習當中java
提到註解,大多數人應該都不默認,在咱們程序中見到的@Override,@Deprected,@SupressWarnings等等,這些都是註解,只不過是系統本身封裝好的,而咱們平時比較少去深刻理解是怎樣實現的?程序員
Annotation(註解)就是Java提供了一種元程序中的元素關聯任何信息和着任何元數據(metadata)的途徑和方法。Annotion(註解)是一個接口,程序能夠經過反射來獲取指定程序元素的Annotion對象,而後經過Annotion對象來獲取註解裏面的元數據。面試
根據註解參數的個數,咱們能夠將註解分爲三類:數組
根據註解使用方法和用途,咱們能夠將Annotation分爲三類:微信
元註解的做用就是負責註解其餘註解。Java5.0定義了4個標準的meta-annotation類型,它們被用來提供對其它annotation類型做說明。Java5.0定義的元註解:ide
@Documented 是否會保存到 Javadoc 文檔中函數
@Retention 保留時間,可選值學習
SOURCE(源碼時),CLASS(編譯時),RUNTIME(運行時),默認爲 CLASS,SOURCE 大都爲 Mark Annotation,這類 Annotation 大都用來校驗,好比 Override, SuppressWarnings測試
ANONOTATION_TYPE(註解類型聲明), PACKAGE(包) TYPE (類,包括enum及接口,註解類型) METHOD (方法) CONSTRUCTOR (構造方法) FIFLD (成員變量) PARAMATER (參數) LOCAL_VARIABLE (局部 變量)spa
元數據從metadata一詞譯來,就是「關於數據的數據」的意思。 元數據的功能做用有不少,好比:你可能用過Javadoc的註釋自動生成文檔。這就是元數據功能的一種。總的來講,元數據能夠用來建立文檔,跟蹤代碼的依賴性,執行編譯時格式檢查,代替已有的配置文件。若是要對於元數據的做用進行分類,目前尚未明確的定義,不過咱們能夠根據它所起的做用,大體可分爲三類:
其餘知識點暫時不介紹,我的以爲一會兒介紹太多概念很難消化。下面讓咱們一塊兒結合例子來使用它。
自定義註解大概可分爲如下三個步驟:
這些類型和它們所支持的類在java.lang.annotation包中能夠找到。
/* * 定義註解 MethodInfo * 爲方便測試:註解目標爲類 方法,屬性及構造方法 * 註解中含有三個元素 id ,name和 gid; * id 元素 有默認值 0 */
@Documented
@Target({ElementType.TYPE,ElementType.METHOD,
ElementType.FIELD,ElementType.CONSTRUCTOR})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MethodInfo {
String name() default "xujunTest";
int id() default 0;
Class<Long> gid();
}
複製代碼
(1). 經過 @interface 定義,註解名即爲自定義註解名,這裏註解名爲MethodInfo
(2). 註解配置參數名爲註解類的方法名,且:
a. 全部方法沒有方法體,沒有參數沒有修飾符,實際只容許 public & abstract 修飾符,默認爲 public,不容許拋異常
b. 方法返回值只能是基本類型,String, Class, annotation, enumeration 或者是他們的一維數組
c. 若只有一個默認屬性,可直接用 value() 函數。一個屬性都沒有表示該 Annotation 爲 Mark Annotation
(3). 能夠加 default 表示默認值,如
String name() default "xujunTest";
複製代碼
/** * 這個類專門用來測試註解使用 * @author xujun */
//類成員註解
@MethodInfo (name="type",gid=Long.class)
public class UserAnnotation {
//類成員註解
@TestA(name="param",id=1,gid=Long.class)
private Integer age;
//構造方法註解
@TestA (name="construct",id=2,gid=Long.class)
public UserAnnotation(){
}
//類方法註解
@TestA(name="public method",id=3,gid=Long.class)
public void a(){
Map<String,String> m = new HashMap<String,String>(0);
}
//類方法註解
@TestA(name="protected method",id=4,gid=Long.class)
protected void b(){
Map<String,String> m = new HashMap<String,String>(0);
}
//類方法註解
@TestA(name="private method",id=5,gid=Long.class)
private void c(){
Map<String,String> m = new HashMap<String,String>(0);
}
public void b(Integer a){
}
}
複製代碼
(1) 運行時 Annotation 指 @Retention 爲 RUNTIME 的 Annotation,可手動調用下面經常使用 API 解析
method.getAnnotation(AnnotationName.class);
method.getAnnotations();
method.isAnnotationPresent(AnnotationName.class);
複製代碼
其餘 @Target 如 Field,Class 方法相似
/* * 根據註解類型返回方法的指定類型註解 */
MethodInfo annotation = (MethodInfo) constructor
.getAnnotation(MethodInfo.class);
複製代碼
Annotation[] annotations = clazz.getAnnotations();
for (Annotation annotation : annotations) {
MethodInfo methodInfo = (MethodInfo) annotation
}
複製代碼
/* * 判斷構造方法中是否有指定註解類型的註解 */
boolean hasAnnotation = constructor
.isAnnotationPresent(MethodInfo.class);
if (hasAnnotation) {
/* * 根據註解類型返回方法的指定類型註解 */
MethodInfo annotation = (MethodInfo) constructor
.getAnnotation(MethodInfo.class);
}
複製代碼
public class ParseAnnotation {
static String className="com.xujun.animation.test.UserAnnotation";
/** * 簡單打印出UserAnnotation 類中所使用到的類註解 該方法只打印了 Type 類型的註解 * * @throws ClassNotFoundException */
public static void parseTypeAnnotation() throws ClassNotFoundException {
Class clazz = Class.forName(className);
Annotation[] annotations = clazz.getAnnotations();
for (Annotation annotation : annotations) {
MethodInfo testA = (MethodInfo) annotation;
System.out.println("id= \"" + testA.id() + "\"; name= \""
+ testA.name() + "\"; gid = " + testA.gid());
}
}
/** * 簡單打印出UserAnnotation 類中所使用到的方法註解 該方法只打印了 Method 類型的註解 * * @throws ClassNotFoundException */
public static void parseMethodAnnotation() {
Method[] methods = UserAnnotation.class.getDeclaredMethods();
for (Method method : methods) {
/* * 判斷方法中是否有指定註解類型的註解 */
boolean hasAnnotation = method.isAnnotationPresent(MethodInfo.class);
if (hasAnnotation) {
/* * 根據註解類型返回方法的指定類型註解 */
MethodInfo annotation = method.getAnnotation(MethodInfo.class);
System.out.println("method = " + method.getName() + " ; id = "
+ annotation.id() + " ; description = "
+ annotation.name() + "; gid= " + annotation.gid());
}
}
}
/** * 簡單打印出UserAnnotation 類中所使用到的方法註解 該方法只打印了 Method 類型的註解 * * @throws ClassNotFoundException */
public static void parseConstructAnnotation() {
Constructor[] constructors = UserAnnotation.class.getConstructors();
for (Constructor constructor : constructors) {
/* * 判斷構造方法中是否有指定註解類型的註解 */
boolean hasAnnotation = constructor
.isAnnotationPresent(MethodInfo.class);
if (hasAnnotation) {
/* * 根據註解類型返回方法的指定類型註解 */
MethodInfo annotation = (MethodInfo) constructor
.getAnnotation(MethodInfo.class);
System.out.println("constructor = " + constructor.getName()
+ " ; id = " + annotation.id() + " ; description = "
+ annotation.name() + "; gid= " + annotation.gid());
}
}
}
public static void main(String[] args) throws ClassNotFoundException {
parseTypeAnnotation();
parseMethodAnnotation();
parseConstructAnnotation();
}
}
複製代碼
運行以上測試程序,將能夠看到如下輸出結果
id= "0"; name= "type"; gid = class java.lang.Long method = c ; id = 5 ; description = private method; gid= class java.lang.Long method = b ; id = 4 ; description = protected method; gid= class java.lang.Long method = a ; id = 3 ; description = public method; gid= class java.lang.Long constructor = com.xujun.animationdemo.UserAnnotation ; id = 2 ; description = construct; gid= class java.lang.Long
轉載請註明原博客地址:
掃一掃,歡迎關注個人微信公衆號 stormjun94(徐公碼字), 目前是一名程序員,不只分享 Android開發相關知識,同時還分享技術人成長曆程,包括我的總結,職場經驗,面試經驗等,但願能讓你少走一點彎路。