Java的Annotation在平常開發,特別是java web開發中使用普遍,各類web框架,測試框架多多少少都會引入一些註解。若對java註解有一個全面深刻的瞭解,對於咱們的開發工做會有很大的幫助。html
Annotation是做用於java程序元數據的特殊類型。自己和程序的邏輯隔離,程序的運行邏輯不會被Annotation影響。所以,Annotation在程序中的做用僅限於提供一種信息,定義Annotaiton時即把這種信息和被Annotation修飾的class,method,package等關聯了起來。感興趣的外部程序(如編譯器,運行時檢查系統,框架,工具等)便可經過反射機制從被修飾類型上獲取到關聯的Annotation,從而實現特殊的功能。所以能夠說Annotaion是一種特殊的註釋,是給框架,編譯器,運行時檢查系統等外部系統看的註釋。java
Anntation能夠在運行時使用,也能夠在編譯時使用。在運行時,Annotation是class類的一部分,獲取Annotation信息須要經過Class對象。而在編譯期使用註解則須要特殊的工具,本文不討論。web
Annotation是java中一種獨立的類型,用@interface聲明,且繼承了Annotation接口。定義一個Annotation的目的無非是想註明一個類,一個field,乃至一個package擁有某項信息。所以Anntation的定義是很是輕量的,惟一要作的也只是定義在@interface體中定義一些name value對,定義形式相似於沒有方法體的方法。這些name能夠有默認值也能夠沒有默認值。Annotation的域可使用8種基本類型和class,Enum等類型,例以下面代碼所示:oracle
@interface TestAnnotation{ public String testNmae(); public String testNameValue() default "test"; public int testIntName() default 10; }
此外,Annotation定義時須要採用一些元註解來指定註解的屬性,這些元註解做用於自定義註解,指定了自定義註解的可見範圍,做用對象,是否可繼承等屬性,具體可見https://docs.oracle.com/javas...。框架
@Retention @Target @Documented @Inherited @Repeatable
Annotation的使用包括在編譯時使用和運行時使用,編譯時使用須要Annotation工具,此文不討論,在運行時使用須要用反射方法去獲取註解信息,而後根據獲取到的註解信息作自定義的處理。工具
處理Anntation和反射應用同樣。首先獲取須要處理的類或者方法等的Class對象,再用isAnnotationPresent方法檢測指定的Anntation類型是否註解了該類,也能夠用Class對象的getAnnotation方法獲取到指定的Anntation對象。測試
代碼清單1.1是一個簡單的Annotation使用示例。this
//1.1 // Description.java @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented public @interface Description{ String value(); } //AnnotationTest.java @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @Documented public @interface AnnotationTest{ String name(); } //ClassWithAnnotation.java @Description("this is a class with description annotation") public class ClassWithAnnotation { @AnnotationTest(name="this is a method with annotation") public void doSth(){ System.out.println("i have a annotation"); } } //AnalysisAnnotation .java public class AnalysisAnnotation { public static void main(String[] args){ try{ Class<?> rtClass = Class.forName("annotation.ClassWithAnnotation"); Method[] methods = rtClass.getMethods(); boolean desctionExist = rtClass.isAnnotationPresent(Description.class); if(desctionExist){ Description description = rtClass.getAnnotation(Description.class); System.out.println("class's annotation value:"+description.value()); for(Method method:methods){ if(method.isAnnotationPresent(AnnotationTest.class)){ AnnotationTest annotation = method.getAnnotation(AnnotationTest.class); System.out.println("method's anntation value:"+annotation.name()); } } } } catch(ClassNotFoundException e){ e.printStackTrace(); } } }
運行結果如上。能夠看到經過AnalysisAnnotation類中的反射方法獲取到了ClassWithAnnotation這個類的註解以及其方法的註解。編譯時代碼便可這樣獲取到註解信息,加以利用。運行時註解的一個常見例子是junit等測試框架,或根據註解來實現一些功能。spa
除了運行時可使用註解,在編譯時也能夠用註解,這個須要特殊的工具支持。經常使用來自動生成代碼。code