Java 語言特性之 Annotation 註解

利用 Java 的反射機制,能夠在運行時獲取 Java 類的註解信息。html

註解

註解的特性

註解是 Java 5 的一個新特性,是插入代碼中的一種註釋或者說是元數據。註解並非程序代碼,能夠對程序做出解釋,相似於註釋。可是註解能夠被相關程序讀取(例如編譯器)。java

註解能夠用在兩個時刻:web

  • 在編譯期間,編譯工具會對註解進行處理
  • 在運行期間,使用 Java 反射機制進行處理

註解格式及用法

註解的格式:註解以 @ 開頭,後面跟註釋名,還能夠加參數。數組

註解使用的地方:package,class,method,field 上均可以使用註解。ide

  • 類註解:
@MyAnnotation(name="someName",  value = "Hello World")
public class TheClass {
}
  • 方法註解:
@Override
public String toString() { // 這裏若是方法名寫錯,會報錯
	return "";
}

註解的定義

註解的定義與接口的定義類似,可是須要在 interface 關鍵字前加 @ 符號:svg

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}

元註解 meta-annotation

元註解負責註解其餘註解。Java 定義了4個標準的元註解類型,用來對其它 註解類型做說明:工具

@Target

@Target 用於描述註解的使用位置。例如 @Target(ElementType.TYPE) 表示這個註解只能用在類型上面(好比類跟接口)。參數能夠同時指定多個值,例如@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})。ElementType 的可用值有:spa

  • CONSTRUCTOR:用於構造器
  • FIELD:用於字段
  • LOCAL_VARIABLE:用於局部變量
  • METHOD:用於方法
  • PACKAGE:用於包
  • PARAMETER:用於參數
  • TYPE:用於類、接口(包括註解類型) 或enum聲明

@Retention

@Retention 用於描述註解的生命週期。可取值有:code

  • SOURCE:在源文件中有效,編譯時丟棄
  • CLASS:在class文件中有效,運行時丟棄
  • RUNTIME:在運行時有效

@Documented

@Documented 用於描述是否能夠被 javadoc 之類的工具文檔化。@Documented 是標記註解,沒有成員。xml

@Inherited

@Inherited 用於描述某個被標註的類型是被繼承的。若是一個使用了 @Inherited 修飾的annotation類型被用於一個class,則這個註解將被用於該class的子類。

當@Inherited 類型標註的註解的Retention是RetentionPolicy.RUNTIME,則反射API加強了這種繼承性。若是咱們使用 java.lang.reflect 反射機制去查詢一個@Inherited 類型的註解時,反射代碼檢查將展開工做:檢查class和其父類,直到發現指定的annotation類型被發現,或者到達類繼承結構的頂層。

內置註解

@Override

定義在 java.lang.Override 中,此註解只能用於修飾方法,表示重寫父類中的方法。

@Deprecated

定義在 java.lang.Deprecated 中,能夠用於修飾方法、屬性或類,表示方法、屬性或類已經廢棄,不建議使用。

@SuppressWarnings

定義在 java.lang.SuppressWarnings 中,抑制編譯時的警告信息。能夠指定如下的一個或多個參數,例如 `@SuppressWarngins(value={「unchecked」, 「path」}):

  • all:抑制全部警告
  • deprecate:抑制廢棄方式、屬性或類的警告
  • unchecked:抑制未檢查的警告,例如使用集合時未指定泛型
  • path:路徑、文件不存在的警告
  • finally:抑制 finally 子句不能完成時的警告

自定義註解

使用 @interface 自定義註解時,自動繼承 java.lang.annotation.Annotation 接口。註解不能繼承其餘的註解或接口。

@interface 用來聲明一個註解,其中的每個方法其實是聲明瞭一個配置參數。方法的名稱就是參數的名稱,返回值類型就是參數的類型(返回值類型只能是基本數據類型(int,float,boolean,byte,double,char,long,short)、Class、String、enum 及這些類型對應的數組)。能夠經過default來聲明參數的默認值。

定義註解的語法:

public @interface 註解名 {定義體}
  • 例如,註解使用:
@MyAnnotation(name="someName",  value = "Hello World")
public class TheClass {
}
  • 註解定義:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)

public @interface MyAnnotation {
  public String name();
  public String value();
}

訪問註解

只要是 Runtime 級別的註解,無論是類、方法、參數、變量註解均可以在運行時經過反射機制加載類後,進行訪問,具體方法能夠參考 這裏

Class aClass = TheClass.class;
Annotation annotation = aClass.getAnnotation(MyAnnotation.class);

if(annotation instanceof MyAnnotation){
    MyAnnotation myAnnotation = (MyAnnotation) annotation;
    System.out.println("name: " + myAnnotation.name());
    System.out.println("value: " + myAnnotation.value());
}
相關文章
相關標籤/搜索