使用Java自定義Annotation

看一個最簡單的annotation

package com.cts.elt.annotation;

import java.lang.annotation.Documented;

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

importjava.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@Documented

public @interface MyAnnotation1 {

        String value();

}

1.  Annotation需要聲明爲@interface這樣的東西

2.  @Target(ElementType.TYPE)

代碼這個annotation必須且一定要註釋在什麼語句上面

ElementType.TYPE代表此Annotation必須聲明在public class Student{…}的上面,而不能寫在任何的method{}(方法)或者是field(屬性)的上方。

@Target:  表示該註解可以用於什麼地方。可用ElementType枚舉類型主要有:

              TYPE : 類、接口或enum聲明

              FIELD: 域(屬性)聲明

              METHOD: 方法聲明

              PARAMETER: 參數聲明

              CONSTRUCTOR: 構造方法聲明

              LOCAL_VARIABLE:局部變量聲明

              ANNOTATION_TYPE:註釋類型聲明

              PACKAGE: 包聲明

3.  Retention如果設爲了RUNTIME,代表此annotation的具體實現可以在運行時用類反射來實現

我們看到了,annotation一般爲一個@interface,也沒啥具體的implementation(實現)

怎麼實現這個annotation呢?類反射

@Retention: 表示需要在什麼級別保存該註解信息。

可用RetentionPolicy枚舉類型主要有:

             SOURCE: 註解將被編譯器丟棄。

             CLASS  :  註解在class文件中可能。但會被VM丟棄。

             RUNTIME: VM將在運行時也保存註解(如果需要通過反射讀取註解,則

使用該值)。

4. @Documented

@Documented:  將此註解包含在Javadoc中。

上面這個MyAnnotation1.class文件包含一個值,下面來一個含有兩個值的annotation

package com.cts.elt.annotation;

import java.lang.annotation.Documented;

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

importjava.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

@Documented

public @interface MyAnnotation2 {

        String description();

        boolean isAnnotation();

}

 

關鍵是來看這兩個自定義annotation的用法:

package com.cts.elt.annotation;

@MyAnnotation1("this isannotation1")

public class AnnotationDemo {

        @MyAnnotation2(description = "this is annotation2", isAnnotation =true)

        public void sayHello() {

                  System.out.println("hello world!");

        }

}

如果把@MyAnnotation1與@MyAnnotation2的位置換一換,會怎麼樣?請自己動手在eclipse裏試試看,嘿嘿,就知道這個Retention的用法了

自定義annotation高級篇

首先,網上的一些關於自定義annotation教程所舉的例子都不太好!

就2個例子,然後一幫子人在那邊到處COPY這兩個例子然後到處轉發,搞得來大家雲裏霧裏一頭霧水,同時一羣企業的面試官也就喜歡拿這個自定義annotation來作面試題,好像會個annotation就能給Senior software engineer了。

其實Annotation就是類反射加點枚舉,比個數據結構裏的冒泡排序還簡單,沒這麼誇張,關鍵是例子舉的不好,現在來看看下面這個例子。

通過例子來看一個簡單的Annotation

Hibernate的機制是可能通過JAVA類然後逆向成數據庫裏的某個表,大家還記得吧?

比如說

Student.java文件

如果你這樣寫:

 

@Table(name=”T_STUDENT”)

Public class Student{…}

代表這個類對應的數據庫表叫T_STUDENT

如果再有下面這樣的寫法:

Public class Student{

        Private String id=””;

    @Id(init=1)

Public voidsetName(String id){

            This.id=id;

}

}

就代表id這個field是一個主鍵,它的初始值爲1。

好了,現在開始我們自己的例子,設有一CLASS叫Student,其中有三個fields:

private String name = "";

private int age = 0;

private String studentId = "";

相應的每一個field有一對的set, get方法

 

然後我在每個set方法上造一個annotation叫ValueBind的註解,其作用是:

只要set方法上帶有ValueBind註解,它就會根據這個字段的類型把一個默認值,自動賦給Student類中相對應的field。

先來看一下Student類:

package com.cts.elt.annotation;

import java.io.Serializable;

importcom.cts.elt.annotation.ValueBind.fieldType;

public class Student implementsSerializable {

 

        private String name = "";

 

        public String getName() {

                  return name;

        }

        @ValueBind(type = fieldType.STRING, value ="aa")

        public void setName(String name) {

                  this.name = name;

        }

        public int getAge() {

                  return age;

        }

        @ValueBind(type = fieldType.INT, value ="30")

        public void setAge(int age) {

                  this.age = age;

        }

        public String getStudentId() {

                  return studentId;

        }

        @ValueBind(type = fieldType.STRING, value ="101")

        public void setStudentId(String studentId) {

                  this.studentId = studentId;

        }

        private int age = 0;

        private String studentId = "";

}

  
 

自定義一個ValueBind的Annotation

這個@ValueBoind就是我的自定義的annotation,裏面有兩個值,來看這個annotation是怎麼做的吧:

package com.cts.elt.annotation;

import java.lang.annotation.Documented;

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

importjava.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

 

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

@Documented

public @interface ValueBind {

        enum fieldType {

                  STRING, INT

        };

        fieldType type();

        String value();

}

夠簡單的吧!

首先這個annotation只能被標註在方法上

其次它含有兩個值,一個是enum類型,一個是String類型

  
 

利用JAVA類反射來實現我們的Annotation

現在來看我們真正的實現(用類反射來實現)

package com.cts.elt.annotation;

import java.lang.reflect.*;

 

public class PersistStudent {

        public static void main(String[] args) throws Exception {

                  Object c = Class.forName("com.cts.elt.annotation.Student")

                                    .newInstance();

                  try {

                           Method[] methodArray = c.getClass().getDeclaredMethods();

                           for (int i = 0; i < methodArray.length; i++) {

                                    if (methodArray[i].isAnnotationPresent(ValueBind.class)) {

                                              ValueBind annotation = methodArray[i]

                                                                .getAnnotation(ValueBind.class);

                                              String type = String.valueOf(annotation.type());

                                              String value = annotation.value();

                                              if (type.equals("INT")) {

                                                       methodArray[i].invoke(c, new Integer[] { new Integer(

                                                                          value) });

                                              } else {

                                                       methodArray[i].invoke(c, new String[] { value });

                                              }

                                    }

                           }

                           Student annotaedStudent = (Student) c;

                           System.out.println("studentId====" + annotaedStudent.getStudentId()

                                              + "  studentnName====" + annotaedStudent.getName()

                                              + "   student Age====" + annotaedStudent.getAge());

                  } catch (Exception e) {

                           throw new Exception(e);

                  }

        }

}

運行完畢後顯示:

studentId====101  studentnName====aa   studentAge====30

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