Java 使用反射处理注解
生活随笔
收集整理的這篇文章主要介紹了
Java 使用反射处理注解
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
Java 使用反射處理注解
自定義注解的格式:
[public|final] @interface 注解名//@interface 表明:這是一個自定義注解 {注解元素//注解元素 是無參數(shù)的方法 }// 注解元素的格式: 數(shù)據(jù)類型 注解元素名() [default 默認值]例子:
//自定義注解: package test;import java.lang.annotation.*; @Target({ElementType.TYPE, ElementType.METHOD}) //注解作用于類和方法的聲明上 @Retention(RetentionPolicy.RUNTIME) //注解在運行時有效 public @interface UseAnno {String value() default "user"; }//使用自定義注解UseAnno package test; @UseAnno//在類上使用注解 public class AnnoC {@UseAnno("注解作用在方法上")//在方法上使用注解public void method() {System.out.println("在方法上使用注解");} }使用反射處理注解
利用反射可以在運行時動態(tài)獲取類的相關信息,如類的方法、屬性、構造方法。還可以創(chuàng)建對象、調(diào)用方法等。利用反射也可以獲取注解的相關信息。
反射是在運行時獲取相關信息的,要使用反射獲取注解的相關信息,這個注解必須是用@Retention(RetentionPolicy.RUNTIME)聲明的。
java.lang.reflect.AnnotatedElement接口定義了使用反射讀取注解信息的方法:
Annotation getAnnotation(Class annotationType) //若存在該元素指定類型的注解,則返回這些注解,否則返回null。 Annotation[] getAnnotations() //返回此元素上存在的所有注解。包括繼承的 Annotation[] getDeclaredAnnotations() //返回該元素上存在的所有注解,不包括繼承的。/*對于getAnnotations()和getDeclaredAnnotations():如果沒有注釋直接存在于此元素上,則返回長度為零的一個數(shù)組。該方法的調(diào)用者可以隨意修改返回的數(shù)組;這不會對其他調(diào)用者返回的數(shù)組產(chǎn)生任何影響。*/ java.lang.Package.isAnnotationPresent: public boolean isAnnotationPresent(類<? extends Annotation> annotationClass)//若指定類型的注解存在于此元素上,則返回true,否則返回false 例: aField.isAnnotationPresent(ApplianceMaker.class) //意思是,判斷aField字段的注解是不是ApplianceMaker 類型 //自定義注解: package test;import java.lang.annotation.*; @Target({ElementType.TYPE, ElementType.METHOD}) //注解作用于類和方法的聲明上 @Retention(RetentionPolicy.RUNTIME) //注解在運行時有效 public @interface UseAnno {String value() default "user"; }//使用自定義注解UseAnno package test; @UseAnno//在類上使用注解 public class AnnoC {@UseAnno("注解作用在方法上")//在方法上使用注解public void method() {System.out.println("在方法上使用注解");} } package test; import java.lang.annotation.Annotation; import java.lang.reflect.Method; //利用反射獲取注解的值 public class ReflectAnno {public static void main(String[] args) {try {Class c = Class.forName("test.AnnoC");//獲取 使用注解的類 AnnoC 的Class對象cClass cUse = Class.forName("test.UseAnno");//獲取 注解類UseAnno 的Class對象cUserAnnotation anno = c.getAnnotation(cUse);//獲取AnnoC類上使用的cUse注解 annoif(anno != null) {UseAnno a = (UseAnno) anno;System.out.println("AnnoC類上的注解: " + a.value());}Method m = c.getDeclaredMethod("method");Annotation an = m.getAnnotation(cUse);//獲取method()方法上使用的cUse注解 anif(an != null) {UseAnno a = (UseAnno) an;System.out.println("method()方法上的注釋: " + a.value());}}catch(Exception e) {e.printStackTrace();}} } /*輸出 AnnoC類上的注解: user method()方法上的注釋: 注解作用在方法上 */ //例子2 package test; import java.lang.annotation.*; import java.lang.reflect.*; @Retention(RetentionPolicy.RUNTIME) // 元注解,運行時保留注解,必須有,否則注解值讀不出 @interface ApplianceMaker // 定義注解 {// 定義注解元素,都有默認值public String type() default "TV";public String id() default "001";public String maker() default "PandaTv";public String address() default "BJ"; }@Retention(RetentionPolicy.RUNTIME) @interface ApplianceSaler // 定義注解 {public String name() default "TM";public String id() default "001";public String address() default "HK"; }@Retention(RetentionPolicy.RUNTIME) @interface AppliancePrice // 定義注解 {// 注解元素只有一個,名為valuepublic int value() default 1200; }class Appliance {// 為域maker 加注解,給部分元素賦值,其余用默認值// 如果注解元素都用默認值,則直接寫@ApplianceMaker@ApplianceMaker(type = "電腦", id = "201")public String maker;@ApplianceSaler(name = "JD", id = "222", address = "WH")public String saler; // 域有注解@AppliancePrice(999) // 也可以寫成"value=999",因為只有一個,此處只寫出值即可public int price; // 域有注解public void setMaker(String m) {maker = m;}public String getMaker() {return maker;}public void setSaler(String saler) {this.saler = saler;}public String getSaler() {return saler;}public void setPrice(int price) {this.price = price;}public int getPrice() {return price;} }public class Test {public static void main(String args[]) {System.out.println(readAnnotation(Appliance.class));}// 讀注解信息private static String readAnnotation(Class aClass) {String maker = "制造商:";String saler = "銷售商:";String price = "價格:";Field fields[] = aClass.getDeclaredFields(); // 獲取Appliance 類的所有字段for (Field aField : fields) // 對每一個字段判斷其注解的類型{// 字段的注解是ApplianceMaker 類型if (aField.isAnnotationPresent(ApplianceMaker.class)) {ApplianceMaker aMaker; // 聲明一個注解變量// 調(diào)用getAnnotation()方法獲得在aField 域上的注解“實例”aMaker = (ApplianceMaker) aField.getAnnotation(ApplianceMaker.class);maker += aMaker.type() + " "; // 獲取type 元素的值,其余與此相同maker += aMaker.id() + " ";maker += aMaker.maker() + " ";maker += aMaker.address() + "\n";}// 字段的注解是ApplianceSaler 類型else if (aField.isAnnotationPresent(ApplianceSaler.class)) {ApplianceSaler aSaler;aSaler = (ApplianceSaler) aField.getAnnotation(ApplianceSaler.class);saler += aSaler.name() + " ";saler += aSaler.id() + " ";saler += aSaler.address() + "\n";}// 字段的注解是AppliancePrice 類型else if (aField.isAnnotationPresent(AppliancePrice.class)) {AppliancePrice thePrice;thePrice = (AppliancePrice) aField.getAnnotation(AppliancePrice.class);price += thePrice.value();}}return maker + saler + price;} } /*輸出: 制造商:電腦 201 PandaTv BJ 銷售商:JD 222 WH 價格:999 */總結
以上是生活随笔為你收集整理的Java 使用反射处理注解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CBOW模型正向传播、矩阵乘积层实现
- 下一篇: 利用DHT22和Arduino测量温湿度