Java自定義註解的實現

註解是Java 1.5引入的,目前已經被廣泛引用於各種Java框架,如Hibernate,Spring等。首先介紹三個Java內置的註解:

1. @Override,重寫(覆蓋)註解,當我們想要重寫父類的某個方法時,可以使用該註解告訴編譯器我們正在覆蓋一個父類方法。這樣當父類的方法發生變化是編譯器會報錯告知我們。

2. @Deprecated,標記已經過時(棄用)的方法,通過該註解我們可以將某一個方法申明爲棄用狀態。

3. @SuppressWarning,該註解告知編譯器忽略某些警告。

當然框架中的註解是非常多的,不再一一介紹,下面我們來實現自定義註解,看如何定義我們自己的註解:

package com.test.ann;

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;

/*
 * 下面四個註解爲Java5.0定義的四個標準元註解,是用來註解其他註解的
 */
//@Target說明了目前定義的註解可以使用的範圍,取值常用的有如下幾個:
//CONSTRUCTOR:用於描述構造器
//PACKAGE:用於描述包
//PARAMETER:用於描述參數
//METHOD:用於描述方法
//TYPE:用於描述類,接口(包括註解類型)或enum聲明
//如果該註解不存在,說明定義的註解可以在任何程序元素上使用
@Target({ElementType.METHOD,ElementType.TYPE})

//@Retenttion定義了註解的生命週期,取值有如下三個:
//SOURCE:只在源文件中有效(即源文件中保留)
//CLASS:在class文件中有效(class文件中保留)
//RUNTIME:在運行時有效(一般都使用此參數,如果使用前兩個則無法在運行時解析註解)
@Retention(RetentionPolicy.RUNTIME)

//@Inherited爲標記註解,沒有參數,加上此註解,說明當使用我們現在定義的註解的類被子類繼承時,註解也會繼承到子類
@Inherited

//@Documented,也是標記註解,說明定義的註解可以被javadoc等工具文檔化
@Documented

//使用@interface關鍵字定義註解
public @interface Description {
	/*
	 * 註解方法的定義(其實在註解中也可以看做成員變量)有如下的規定:
	 * 1.不能有參數和拋出異常
	 * 2.方法返回類型只能爲八種基本數據類型和字符串,枚舉和註解以及這些類型構成的數組
	 * 3.可以包含默認值,通過default實現
	 * 4.如果只有一個方法(成員變量),最好命名爲value
	 */
	String value();
	int count() default 1; //默認值爲1
}
下面我們再實現一個使用了我們上面定義的Description註解的類:

package com.test.ann;

//在類上使用定義的Description註解
@Description(value="class annotation",count=2)
public class Person {
	
	private String name;
	private int age;
	
	//在方法上使用定義的Description註解
	@Description(value="method annotation",count=3)
	public String speak() {
		return "speaking...";
	}
}
最後就是如何解析註解了,在實現過中使用了反射:

package com.test.ann;

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

//註解解析類
public class ParseAnn {
	
	public static void main(String[] args){
		//使用類加載器加載類
		try {
			Class c = Class.forName("com.test.ann.Person");//加載使用了定義註解的類
			//找到類上的註解
			boolean isExist = c.isAnnotationPresent(Description.class);
			if(isExist){
				//拿到註解示例
				Description d = (Description)c.getAnnotation(Description.class);
				System.out.println(d.value());
			}
			//找到方法上的註解
			Method[] ms = c.getMethods();
			for(Method m : ms){
				boolean isMExist = m.isAnnotationPresent(Description.class);
				if(isMExist){
					Description d = (Description)m.getAnnotation(Description.class);
					System.out.println(d.value());
				}
			}
			//另外一種註解方式
			for(Method m:ms){
				Annotation[] as = m.getAnnotations();
				for(Annotation a:as){
					if(a instanceof Description){
						Description d = (Description)a;
						System.out.println(d.value());
					}
				}
				
			}
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}




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