自定義Annotation(註解)

Java語言解釋器會忽略註解,由第三方工具對註解進行處理。如使用Javadoc工具生成和源代碼配套的使用文檔。這些工具可以利用代碼中的註解信息來更改目標程序的邏輯。

通過定義一個自定義註解來標哪些業務方法需要測試,實例代碼如下:

1、定義註解類

/*
 * 使用@interface修飾符定義註解類
 * 
 * @Retention聲明註解的保留期限,有以下選擇值:
 * 
 * (1)SOURCE  註解在字節碼中不保留
 * (2)CLASS 進入目標類的字節碼文件中,但類加載器在加載字節碼文件時不會將註解加載到JVM,所以運行期間獲取不到
 * (3)RUNTIME 在運行期間可通過反射獲取類中註解的信息
 * 
 * Target 聲明使用該註解的目標類型
 * 
 * (1)TYPE 類、接口、註解類、Enum聲明
 * (2)FIELD 類成員變量或常量聲明
 * (3)METHOD 方法聲明
 * (4)PARAMETER 參數聲明
 * (5)CONSTARUCTOR 構造函數
 * (6)LOCAL_VARIABLE 局部變量
 * (7)ANNOTATION_TYPE 註解類聲明
 * (8)PACKAGE 包聲明
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface NeedTest {
	/*
	 * 成員以無入參無拋出異常的方式聲明
	 * 可以通過default爲成員指定一個默認值,也可以不指定
	 * 成員類型是受限的,合法的類型包括原始類型及其封裝類(對象類型和List類型非法)
	 *  
	 */
	boolean value() default false; // 只有一個成員方法時,名必須取爲value()
}

2、目標類

public class ForumService {
	@NeedTest(true)   // 可以省略成員名和賦值符號
	public void deleteForum(int forumId) {
		System.out.println("刪除論壇模塊:" + forumId);
	}

	@NeedTest(value = false)
	public void deleteTopic(int topicId) {
		System.out.println("刪除論壇主題:" + topicId);
	}
}

3、測試類

public class TestTool {

	public static void main(String[] args) {
		Class clazz = ForumService.class;
		Method[] methods = clazz.getDeclaredMethods();
		for (Method method : methods) {
			NeedTest nt = method.getAnnotation(NeedTest.class); // Package、Method、Filed等反射對象都提供了訪問註解的方法
			if (nt != null) {
				if (nt.value()) {
					System.out.println(method.getName() + "()需要測試");
				} else {
					System.out.println(method.getName() + "()不需要測試");
				}
			}
		}
	}
}

運行的結果如下:

deleteForum()需要測試
deleteTopic()不需要測試


下面來看一下相對複雜的例子,

註解類

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ValueBind {
        enum fieldType {
                  STRING, INT
        };
        fieldType type();
        String value();
}
目標類

public class Student implements Serializable {

	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 = "";
}

測試類

public class PersistStudent {
     public static void main(String[] args) throws Exception {
         Object c = Class.forName("com.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   student Age====30
是不是非常像JPA的註解呀,其實他們的原理是一樣的。













參考文獻:

http://blog.csdn.net/lifetragedy/article/details/7394910



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