若是沒有用來讀取註解的方法和工做,那麼註解也就不會比註釋更有用處了。使用註解的過程當中,很重要的一部分就是建立於使用註解處理器。Java SE5擴展了反射機制的API,以幫助程序員快速的構造自定義註解處理器。java
註解處理器類庫(java.lang.reflect.AnnotatedElement):
Java使用Annotation接口來表明程序元素前面的註解,該接口是全部Annotation類型的父接口。除此以外,Java在java.lang.reflect 包下新增了AnnotatedElement接口,該接口表明程序中能夠接受註解的程序元素,該接口主要有以下幾個實現類:程序員
java.lang.reflect 包下主要包含一些實現反射功能的工具類,實際上,java.lang.reflect 包全部提供的反射API擴充了讀取運行時Annotation信息的能力。當一個Annotation類型被定義爲運行時的Annotation後,該註解才能是運行時可見,當class文件被裝載時被保存在class文件中的Annotation纔會被虛擬機讀取。數組
AnnotatedElement 接口是全部程序元素(Class、Method和Constructor)的父接口,因此程序經過反射獲取了某個類的AnnotatedElement對象以後,程序就能夠調用該對象的以下四個方法來訪問Annotation信息:app
方法1: T getAnnotation(Class annotationClass): 返回該程序元素上存在的、指定類型的註解,若是該類型註解不存在,則返回null。
方法2:Annotation[] getAnnotations():返回該程序元素上存在的全部註解。
方法3:boolean is AnnotationPresent(Class< ?extends Annotation> annotationClass):判斷該程序元素上是否包含指定類型的註解,存在則返回true,不然返回false.
方法4:Annotation[] getDeclaredAnnotations():返回直接存在於此元素上的全部註釋。與此接口中的其餘方法不一樣,該方法將忽略繼承的註釋。(若是沒有註釋直接存在於此元素上,則返回長度爲零的一個數組。)該方法的調用者能夠隨意修改返回的數組;這不會對其餘調用者返回的數組產生任何影響。ide
一個簡單的註解處理器:工具
/***********註解聲明***************/ /** * 水果名稱註解 */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface FruitName { String value() default ""; } /** * 水果顏色註解 */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface FruitColor { /** * 顏色枚舉 */ public enum Color { BULE, RED, GREEN }; /** * 顏色屬性 */ Color fruitColor() default Color.GREEN; } /** * 水果供應者註解 * */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface FruitProvider { /** * 供應商編號 */ public int id() default -1; /** * 供應商名稱 */ public String name() default ""; /** * 供應商地址 */ public String address() default ""; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 /*********** 註解使用 ***************/ public class Apple { @FruitName("Apple") private String appleName; @FruitColor(fruitColor = Color.RED) private String appleColor; @FruitProvider(id = 1, name = "香蕉集團", address = "廣東省水果大廈") 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); } } } }
/***********main方法***************/ public class FruitRun { public static void main(String[] args) { FruitInfoUtil.getFruitInfo(Apple.class); } } /***********輸出結果***************/ 水果名稱:Apple 水果顏色:RED 供應商編號:1 供應商名稱:香蕉集團 供應商地址:廣東省水果大廈