1. 程式人生 > >自定義註解以及註解解析

自定義註解以及註解解析

上面一篇介紹了註解的基本概念,這篇主要是註解的自定義開發以及解析註解

一.自定義註解:

這裡建立了一個加在方法上以及類上的註解:

package com.ann.test;

import java.lang.annotation.*;

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Description {
    String desc();
    String author();
    int age() default 18;
}

使用:

package com.ann.test;

public class Child implements Person{
    @Override
    @Description(desc="miaoshu",author = "sqz")
    public String name() {
        return null;
    }

    @Override
    public String age() {
        return null;
    }

    @Override
    public String sing() {
        return "zhangsan";
    }
}

這時候是加在類上與方法上的註解,我們把ElementType.TYPE去掉,那麼在類上再加註解就會報錯

二:解析註解:

概念:通過反射獲取類,函式,變數上的執行時註解資訊,從而實現動態控制程式的執行邏輯

註解類定義:

package com.ann.test;

import java.lang.annotation.*;

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Description {
    String value();//此時只有一個成員,只能用value()
}

使用類: 

package com.ann.test;
@Description("i am class annotation")
public class Child implements Person{
    @Override
    @Description("i am method annotation")
    public String name() {
        return null;
    }

    @Override
    public String age() {
        return null;
    }

    @Override
    public String sing() {
        return "zhangsan";
    }
}

解析類:

package com.ann.test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

public class ParseAnno {
    public static void main(String[] args) {
        //1.使用類載入器載入類
        try {
            Class c = Class.forName("com.ann.test.Child");
            //2.找到類上面的註解
            boolean isexists = c.isAnnotationPresent(Description.class);//這個類上是否存在Description註解
            if (isexists){
                //3.如果存在就拿到註解例項
                Description description = (Description) c.getAnnotation(Description.class);
                System.out.println(description.value());//列印屬性
            }
            //4.找到方法上的註解
            Method[] methods = c.getMethods();
            //方式一:
            for (Method m:methods){
                boolean isMeAno = m.isAnnotationPresent(Description.class);
                //如果方法上的註解是Description,就拿到註解例項
                if (isMeAno){
                    Description description = m.getAnnotation(Description.class);
                    System.out.println(description.value());
                }
            }

            //方式二:
            for (Method m:methods){
                //拿到方法上所有註解
                Annotation[] as = m.getAnnotations();
                for (Annotation a :as){
                    if (a instanceof Description){
                        Description d = (Description)a;
                        System.out.println(d.value());
                    }
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

java 中的instanceof 運算子是用來在執行時指出物件是否是特定類的一個例項。instanceof通過返回一個布林值來指出,這個物件是否是這個特定類或者是它的子類的一個例項。

用法: 
         result = object instanceof class 
引數: 
         Result:布林型別。 
         Object:必選項。任意物件表示式。 
         Class:必選項。任意已定義的物件類。 

結果:

注意:如果把註解生命週期改成 CLASS或者SOURCE則不能打印出任何結果,只能是執行時註解

還有就是註解的繼承只能寫在類上,不能加在介面上