Java中自定義註解並通過反射獲取註解屬性值

自定義類註解

package com.uno.ray;  
  
import java.lang.annotation.Documented;  
import java.lang.annotation.ElementType;  
import java.lang.annotation.Inherited;  
import java.lang.annotation.Retention;  
import java.lang.annotation.RetentionPolicy;  
import java.lang.annotation.Target;  
import java.net.Authenticator.RequestorType;  
  
/** 
 * 自定義註解 
 * @author Uno 
 *@Documented:指明該註解可以用於生成doc 
 *@Inherited:該註解可以被自動繼承 
 *@Retention:指明在什麼級別顯示該註解: 
 *  RetentionPolicy.SOURCE 註解存在於源代碼中,編譯時會被拋棄 
    RetentionPolicy.CLASS 註解會被編譯到class文件中,但是JVM會忽略 
    RetentionPolicy.RUNTIME JVM會讀取註解,同時會保存到class文件中 
  @Target:指明該註解可以註解的程序範圍 
    ElementType.TYPE 用於類,接口,枚舉但不能是註解 
    ElementType.FIELD 作用於字段,包含枚舉值 
    ElementType.METHOD 作用於方法,不包含構造方法 
    ElementType.PARAMETER 作用於方法的參數 
    ElementType.CONSTRUCTOR 作用於構造方法 
    ElementType.LOCAL_VERIABLE 作用於本地變量或者catch語句 
    ElementType.ANNOTATION_TYPE 作用於註解 
    ElementType.PACKAGE 作用於包 
 */  
@Documented  
@Inherited  
@Retention(RetentionPolicy.RUNTIME)  
@Target({ElementType.TYPE, ElementType.FIELD})//次註解作用於類和字段上  
public @interface FieldTypeAnnotation {  
    /** 
     *leip 2016年12月3日 
     *TODO 
    **/  
    String type() default "ignore";  
    int age() default 27;  
    String[] hobby(); //沒有指定defalut的,需要在註解的時候顯式指明  
}  

自定義方法註解

package com.uno.ray;  
  
import java.lang.annotation.Documented;  
import java.lang.annotation.ElementType;  
import java.lang.annotation.Inherited;  
import java.lang.annotation.Retention;  
import java.lang.annotation.RetentionPolicy;  
import java.lang.annotation.Target;  
  
/** 
 *  
 * @author Uno 
 * 
 */  
@Documented  
@Inherited  
@Retention(RetentionPolicy.RUNTIME)  
@Target(ElementType.METHOD) //次註解只能作用於方法上  
public @interface MethodAnnotation {  
  
    String desc() default "method1";  
}  

反射類測試

package com.uno.ray;  
  
import java.awt.Dialog.ModalityType;  
import java.lang.reflect.Field;  
import java.lang.reflect.Method;  
import java.util.Arrays;  
  
@FieldTypeAnnotation(type = "class", hobby = { "smoke" })  
public class ReflectAnnotation {  
    /** 
     * leip 2016年12月3日 TODO 
     **/  
    @FieldTypeAnnotation(hobby = { "sleep", "play" })  
    private String maomao;  
  
    @FieldTypeAnnotation(hobby = { "phone", "buy" }, age = 27, type = "normal")  
    private String zhangwenping;  
      
    @MethodAnnotation()  
    public void method1() {  
          
    }  
    @MethodAnnotation(desc="method2")  
    public void method2() {  
          
    }  
  
    public static void main(String[] args) {  
        // 此處要用反射將字段中的註解解析出來  
        Class<ReflectAnnotation> clz = ReflectAnnotation.class;  
        // 判斷類上是否有次註解  
        boolean clzHasAnno = clz.isAnnotationPresent(FieldTypeAnnotation.class);  
        if (clzHasAnno) {  
            // 獲取類上的註解  
            FieldTypeAnnotation annotation = clz.getAnnotation(FieldTypeAnnotation.class);  
            // 輸出註解上的屬性  
            int age = annotation.age();  
            String[] hobby = annotation.hobby();  
            String type = annotation.type();  
            System.out.println(clz.getName() + " age = " + age + ", hobby = " + Arrays.asList(hobby).toString() + " type = " + type);  
        }  
        // 解析字段上是否有註解  
        // ps:getDeclaredFields會返回類所有聲明的字段,包括private、protected、public,但是不包括父類的  
        // getFields:則會返回包括父類的所有的public字段,和getMethods()一樣  
        Field[] fields = clz.getDeclaredFields();  
        for(Field field : fields){  
            boolean fieldHasAnno = field.isAnnotationPresent(FieldTypeAnnotation.class);  
            if(fieldHasAnno){  
                FieldTypeAnnotation fieldAnno = field.getAnnotation(FieldTypeAnnotation.class);  
                //輸出註解屬性  
                int age = fieldAnno.age();  
                String[] hobby = fieldAnno.hobby();  
                String type = fieldAnno.type();  
                System.out.println(field.getName() + " age = " + age + ", hobby = " + Arrays.asList(hobby).toString() + " type = " + type);  
            }  
        }  
        //解析方法上的註解  
        Method[] methods = clz.getDeclaredMethods();  
        for(Method method : methods){  
            boolean methodHasAnno = method.isAnnotationPresent(MethodAnnotation.class);  
            if(methodHasAnno){  
                //得到註解  
                MethodAnnotation methodAnno = method.getAnnotation(MethodAnnotation.class);  
                //輸出註解屬性  
                String desc = methodAnno.desc();  
                System.out.println(method.getName() + " desc = " + desc);  
            }  
        }  
    }  
}  

輸出

com.uno.ray.ReflectAnnotation age = 27, hobby = [smoke] type = class  
maomao age = 27, hobby = [sleep, play] type = ignore  
zhangwenping age = 27, hobby = [phone, buy] type = normal  
method2 desc = method2  
method1 desc = method1 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章