一、什么是注解
注解也叫元數據,例如我們常見的@Override和@Deprecated,注解是JDK1.5版本開始引入的一個特性,
用于對代碼進行說明,可以對包、類、接口、字段、方法參數、局部變量等進行注解。
一般常用的注解可以分為三類:
1、Java自帶的標準注解,包括@Override(標明重寫某個方法)、@Deprecated(標明某個類或方法過時)和@SuppressWarnings(標明要忽略的警告),使用這些注解后編譯器就會進行檢查。
2、類為元注解,元注解是用于定義注解的注解,包括@Retention(標明注解被保留的階段)、@Target(標明注解使用的范圍)、@Inherited(標明注解可繼承)、@Documented(標明是否生成javadoc文檔)
3、類為自定義注解,可以根據自己的需求定義注解
二、注解的用途
在看注解的用途之前,有必要簡單的介紹下XML和注解區(qū)別,
注解:是一種分散式的元數據,與源代碼緊綁定。
xml:是一種集中式的元數據,與源代碼無綁定
當然網上存在各種XML與注解的辯論哪個更好,這里不作評論和介紹,主要介紹一下注解的主要用途:
生成文檔,通過代碼里標識的元數據生成javadoc文檔。
編譯檢查,通過代碼里標識的元數據讓編譯器在編譯期間進行檢查驗證。
編譯時動態(tài)處理,編譯時通過代碼里標識的元數據動態(tài)處理,例如動態(tài)生成代碼。
運行時動態(tài)處理,運行時通過代碼里標識的元數據動態(tài)處理,例如使用反射注入實例
三、注解的實現(xiàn)原理
實現(xiàn)注解三要素:
1、注解聲明
2、使用注解的元素
3、操作注解使其起作用(注解處理器)
注解聲明
首先我們讓看一下java中的元注解(也就是上面提到的注解的注解),總共有4個如下:
@Target,@Retention,@Documented,@Inherited這4個元注解都是在jdk的java.lang.annotation包下面,
@Target:Target說明的是Annotation所修飾的對象范圍。@Retention:
定義了該Annotation被保留的時間長短:某些Annotation僅出現(xiàn)在源代碼中,而被編譯器丟棄;而另一些卻被編譯在class文件中;編譯在class文件中的Annotation可能會被虛擬機忽略,
而另一些在class被裝載時將被讀取(請注意并不影響class的執(zhí)行,因為Annotation與class在使用上是被分離的)。
使用這個元注解可以對Annotation的“生命周期”限制。@Documented:@Documented用于描述其它類型的annotation應該被作為被標注的程序成員的公共API,因此可以被例如javadoc此類的工具文檔化。Documented是一個標記注解,沒有成員
@Inherited:@Inherited元注解是一個標記注解,@Inherited闡述了某個被標注的類型是被繼承的。如果一個使用了@Inherited修飾的annotation類型被用于一個class,
則這個annotation將被用于該class的子類。
注意:@Inheritedannotation類型是被標注過的class的子類所繼承。類并不從它所實現(xiàn)的接口繼承annotation,方法并不從它所重載的方法繼承annotation。
當@Inheritedannotation類型標注的annotation的Retention是RetentionPolicy.RUNTIME,則反射API增強了這種繼承性。如果我們使用java.lang.reflect去查詢一個@Inheritedannotation類型的annotation時,
反射代碼檢查將展開工作:檢查class和其父類,直到發(fā)現(xiàn)指定的annotation類型被發(fā)現(xiàn),或者到達類繼承結構的頂層。
java.lang.reflect.AnnotatedElement接口是所有程序元素(Class、Method和Constructor)的父接口,所以程序通過反射獲取了某個類的AnnotatedElement對象之后,程序就可以調用該對象的如下四個個方法來訪問Annotation信息:
方法1:<TextendsAnnotation>TgetAnnotation(Class<T>annotationClass):返回改程序元素上存在的、指定類型的注解,如果該類型注解不存在,則返回null。
方法2:Annotation[]getAnnotations():返回該程序元素上存在的所有注解。
方法3:booleanisAnnotationPresent(Class<?extendsAnnotation>annotationClass):判斷該程序元素上是否