深入理(li)解(jie)Java:注(zhu)解(jie)(Annotation)--注(zhu)解(jie)處(chu)理(li)器
如果沒有用(yong)來讀取注解(jie)的(de)(de)方法和(he)工(gong)作,那么注解(jie)也(ye)就(jiu)(jiu)不會比注釋更有用(yong)處了(le)。使(shi)用(yong)注解(jie)的(de)(de)過程中,很重要的(de)(de)一部分就(jiu)(jiu)是創建于使(shi)用(yong)注解(jie)處理器(qi)。Java SE5擴(kuo)展了(le)反(fan)射機制的(de)(de)API,以幫助(zhu)程序員快速的(de)(de)構造自定義注解(jie)處理器(qi)。
注解處理器類庫(java.lang.reflect.AnnotatedElement):
Java使(shi)用Annotation接(jie)(jie)口(kou)來代表程(cheng)序(xu)元素前面的注解,該(gai)接(jie)(jie)口(kou)是所有(you)Annotation類型的父接(jie)(jie)口(kou)。除(chu)此之外(wai),Java在java.lang.reflect 包下(xia)(xia)新增了AnnotatedElement接(jie)(jie)口(kou),該(gai)接(jie)(jie)口(kou)代表程(cheng)序(xu)中可以接(jie)(jie)受(shou)注解的程(cheng)序(xu)元素,該(gai)接(jie)(jie)口(kou)主(zhu)要(yao)有(you)如下(xia)(xia)幾個實(shi)現類:
Class:類定義
Constructor:構造器定義
Field:累的成員變量定義
Method:類的方法定義
Package:類(lei)的包定義
java.lang.reflect 包下主要包含一些實現反射功能的工具類,實際上,java.lang.reflect 包所有提供的反射API擴充了讀取運行時Annotation信息的能力。當一個Annotation類型被定義為運行時的Annotation后,該注解才能是運行時可見,當class文件被裝載時被保存在class文件中的Annotation才會被虛擬機讀取。
AnnotatedElement 接口(kou)(kou)是所(suo)有程(cheng)序元(yuan)素(su)(Class、Method和Constructor)的(de)(de)父接口(kou)(kou),所(suo)以程(cheng)序通過反射(she)獲(huo)取了某(mou)個(ge)類的(de)(de)AnnotatedElement對象之(zhi)后,程(cheng)序就可以調(diao)用該(gai)對象的(de)(de)如下四(si)個(ge)個(ge)方法(fa)來訪(fang)問Annotation信息:
方法1:<T extends Annotation> T getAnnotation(Class<T> annotationClass): 返回改程序元素上存在的、指定類型的注解,如果該類型注解不存在,則返回null。
方法2:Annotation[] getAnnotations():返回該程序元素上存在的所有注解。
方法3:boolean is AnnotationPresent(Class<?extends Annotation> annotationClass):判斷該程序元素上是否包含指定類型的注解,存在則返回true,否則返回false.
方法4:Annotation[] getDeclaredAnnotations():返(fan)回(hui)直(zhi)接存在(zai)(zai)于(yu)此(ci)(ci)元(yuan)素上(shang)的(de)(de)所(suo)有注釋。與此(ci)(ci)接口中的(de)(de)其他方法不同(tong),該方法將(jiang)忽(hu)略(lve)繼承的(de)(de)注釋。(如(ru)果沒有注釋直(zhi)接存在(zai)(zai)于(yu)此(ci)(ci)元(yuan)素上(shang),則(ze)返(fan)回(hui)長度(du)為零的(de)(de)一個(ge)數組。)該方法的(de)(de)調用(yong)者可(ke)以隨(sui)意修改返(fan)回(hui)的(de)(de)數組;這(zhe)不會(hui)對其他調用(yong)者返(fan)回(hui)的(de)(de)數組產生任何影響。
一個簡單的注(zhu)解處理器:
/***********注解聲明***************/ /** * 水果名稱注解 * @author peida * */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface FruitName { String value() default ""; } /** * 水果顏(yan)色注解(jie) * @author peida * */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface FruitColor { /** * 顏色(se)枚舉 * @author peida * */ public enum Color{ BULE,RED,GREEN}; /** * 顏色屬性 * @return */ Color fruitColor() default Color.GREEN; } /** * 水果供應者(zhe)注解 * @author peida * */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface FruitProvider { /** * 供應商(shang)編號 * @return */ public int id() default -1; /** * 供(gong)應(ying)商(shang)名稱(cheng) * @return */ public String name() default ""; /** * 供應(ying)商(shang)地址 * @return */ public String address() default ""; } /***********注(zhu)解使用***************/ public class Apple { @FruitName("Apple") private String appleName; @FruitColor(fruitColor=Color.RED) private String appleColor; @FruitProvider(id=1,name="陜西紅富士集團",address="陜西省西安市延安路89號紅富士大廈") private String appleProvider; public void setAppleColor(String appleColor) { this.appleColor = appleColor; } public String getAppleColor() { return appleColor; } public void setAppleName(String appleName) { this.appleName = appleName; } public String getAppleName() { return appleName; } public void setAppleProvider(String appleProvider) { this.appleProvider = appleProvider; } public String getAppleProvider() { return appleProvider; } public void displayName(){ System.out.println("水果的名字是:蘋果"); } } /***********注解處理器***************/ public class FruitInfoUtil { public static void getFruitInfo(Class<?> clazz){ String strFruitName=" 水果名稱:"; String strFruitColor=" 水果顏色:"; String strFruitProvicer="供應商信息:"; Field[] fields = clazz.getDeclaredFields(); for(Field field :fields){ if(field.isAnnotationPresent(FruitName.class)){ FruitName fruitName = (FruitName) field.getAnnotation(FruitName.class); strFruitName=strFruitName+fruitName.value(); System.out.println(strFruitName); } else if(field.isAnnotationPresent(FruitColor.class)){ FruitColor fruitColor= (FruitColor) field.getAnnotation(FruitColor.class); strFruitColor=strFruitColor+fruitColor.fruitColor().toString(); System.out.println(strFruitColor); } else if(field.isAnnotationPresent(FruitProvider.class)){ FruitProvider fruitProvider= (FruitProvider) field.getAnnotation(FruitProvider.class); strFruitProvicer=" 供應商編號:"+fruitProvider.id()+" 供應商名稱:"+fruitProvider.name()+" 供應商地址:"+fruitProvider.address(); System.out.println(strFruitProvicer); } } } } /***********輸(shu)出(chu)結果***************/ public class FruitRun { /** * @param args */ public static void main(String[] args) { FruitInfoUtil.getFruitInfo(Apple.class); } } ==================================== 水(shui)果名(ming)稱(cheng):Apple 水(shui)果顏色:RED 供應商編(bian)號:1 供應商名稱:陜西紅富士集團 供應商地址:陜西省西安市延安路89號紅富士大廈
Java注解的(de)(de)(de)(de)基(ji)礎(chu)知識(shi)點(dian)(見下(xia)(xia)面導圖)基(ji)本都過了一遍,下(xia)(xia)一篇我(wo)們(men)通過設計一個基(ji)于注解的(de)(de)(de)(de)簡單的(de)(de)(de)(de)ORM框(kuang)架(jia),來綜合應用(yong)和進(jin)一步(bu)加深(shen)對注解的(de)(de)(de)(de)各個知識(shi)點(dian)的(de)(de)(de)(de)理解和運用(yong)。

關注 熵減黑客 ,一起學習成長
