Java 自定義註解

LiuJun2Son發表於2016-08-24

自定義註解

第一步:

定義一個Person註解類:

    /**
     * 註解類
     */
    @Retention(RetentionPolicy.RUNTIME)//註解可以保留在執行時期
    @Target({ElementType.TYPE,ElementType.METHOD})//註解可以貼在類和方法上
    public @interface Person {

        //引用型別
        String name() default "liujun";
        //基本資料型別
        int age () default 23;
        //陣列
        String [] loves ();
        //列舉
        Level  level();

    }

解說:

  • @Retention :表示註解可以儲存在哪一個時期。@Retention(RetentionPolicy.RUNTIME)//註解可以保留在執行時期

    自定註解一般都保留在 RUNTIME (執行時期)
    
  • @Target:表示註解可以貼在類,方法上,構造器上等等)位置(

    ElementType.ANNOTATION_TYPE只能修飾Annotation
    
    ElementType.CONSTRUCTOR只能修飾構造方法
    
    ElementType.FIELD只能修飾欄位(屬性),包括列舉常量
    
    ElementType.LOCAL_VARIABLE只能修飾區域性變數
    
    ElementType.METHOD只能修飾方法
    
    ElementType.PACKAGE只能修飾包(少使用)
    
    ElementType.PARAMETER只能修飾引數
    
    ElementType.TYPE只能修飾類,介面,列舉
    
  • @interface : 定義註解類的表示

  • 定義註解裡面的屬性:

    註解裡面的屬性支援(基本資料型別,字元,Class,註解,列舉,陣列)


        //定義一個String 型別的name屬性,預設值為 "liujun"
        String name() default "liujun";
        //定義一個列舉型別的屬性
        Level  level();

附加:

  • @Documented: 使用@Documented標註的標籤會儲存到API文件中.

  • @Inherited: @Inherited標註的標籤可以被子類繼承到.

第二步:

定義一個列舉類:

    public enum Level {
        CEO,PM;
    }

第三步:

定義一個測試類:

    //通過註解注入Person類
    @Person(name="xiaomage",age=1,level=Level.CEO, loves = {"足球","桌球"})
    public class TestAnnotation {

        public static void main(String[] args) {
            Class cls=TestAnnotation.class;
            //這個TestAnnotation類是否存在Person註解
            boolean person=cls.isAnnotationPresent(Person.class);
            if(person){
                //通過反射獲取註解類物件
                Person per=(Person) cls.getAnnotation(Person.class);
                //獲取註解類中的資訊
                System.out.println(per);
                System.out.println(per.name());
                System.out.println(per.age());
                System.out.println(per.level());
                System.out.println(Arrays.toString(per.loves()));
            }
        }

    }

    --------------------------------------------------
    輸出的結果:
    @xmg.day24.Person(name=xiaomage, age=1, level=CEO, loves=[足球, 桌球])
    xiaomage
    1
    CEO
    [足球, 桌球]

解說:

  • @Person : 注入Person註解類,並初始化資料

    //如果註解類的屬性有預設值的可以省略不寫,下面給所有的屬性賦值初始化
    @Person(name="xiaomage",age=1,level=Level.CEO, loves = {"足球","桌球"})
    
  • 獲取Person註解類的物件

    Person per=(Person) cls.getAnnotation(Person.class);
    
  • 獲取Person註解類的資訊

    System.out.println(per.name());
    System.out.println(per.age());
    

第四步:

綜合測試(註解寫在類上,方法上,引數上,欄位上的獲取):

1.修改註解類,擴充套件可註解的範圍和所有的欄位都新增了預設值

    @Retention(RetentionPolicy.RUNTIME)//註解可以保留在執行時期
    @Target({ElementType.TYPE,ElementType.METHOD,ElementType.PARAMETER,ElementType.FIELD})//註解可以貼在類,方法,引數,欄位上
    public @interface Person {

        //引用型別
        String name() default "liujun";
        //基本資料型別
        int age () default 23;
        //陣列
        String [] loves () default {"1","2"};
        //列舉
        Level  level() default Level.CEO;

    }

2.修改測試類:

    //通過註解注入Person類
    @Person(level=Level.CEO, loves = {"足球","桌球"})
    public class TestAnnotation {

    @Person(name="FieldName")
    String name;

    @Person(name="MethodName")
    public static void main(@Person(loves = {"足球2","桌球1"}) String[] args) throws Exception {
            //1.獲取類上的註解
            Class cls=TestAnnotation.class;
            //這個類是否存在Person註解
            boolean person=cls.isAnnotationPresent(Person.class);
            if(person){
                System.out.println("--------------------Class-----------------------------");
                //通過反射獲取註解類
                Person per=(Person) cls.getAnnotation(Person.class);
                //獲取註解類的元素
                System.out.println(per);
                System.out.println(per.name());
                System.out.println(per.age());
                System.out.println(per.level());
                System.out.println(Arrays.toString(per.loves()));
            }

            System.out.println("--------------------Method-----------------------------");
            //2.獲取方法上的註解
            Method m=cls.getDeclaredMethod("main", String [].class);
            //通過反射獲取註解類
            Person per=m.getAnnotation(Person.class);
            //獲取註解類的元素
            System.out.println(per.name());

            System.out.println("----------------------Parameter---------------------------");
            //3.獲取引數上的註解
            Parameter[] parameters = m.getParameters();
            for (Parameter parameter : parameters) {
                Person pers=parameter.getAnnotation(Person.class);
                System.out.println(Arrays.toString(pers.loves()));
            }

            System.out.println("----------------------Field---------------------------");
            //4.獲取欄位上的註解:
            Field declaredField = cls.getDeclaredField("name");
            Person p=declaredField.getAnnotation(Person.class);
            System.out.println(p.name());
        }

    }

解說:

註解資訊的獲取都是通過反射來獲取java中反射的使用

相關文章