Java提供了四種元註解專門用來負責註解其他的註解。
- @Target表示註解可以用於什麼地方,可能的ElementType參數包括
- CONSTRUCTOR,構造器的聲明
- FIFLD:域聲明(包括enum實例)
- LOCAL_VARIABLE:局部變量聲明
- PACKAGE:包聲明
- PARAMETER:參數聲明
- METHOD:方法聲明
- TYPE:類,接口(包括註解類型)或enum聲明
- @Retention表示需要在什麼級別保存該註解信息,可選RetentionPolicy參數包括:
- SOURCE:註解將被編譯器丟棄
- CLASS:註解在class文件中可用,但會被VM丟棄
- RUNTIME:VM將在運行期也保留註解,因此可以通過反射機制讀取註解信息
- @Documented表示此註解包含在Javadoc中
- @Inherited允許子類繼承父類中的註解
下面我們來自定義一個註解,這個註解用來跟蹤我們實現某個需求的一組方法,可以幫助我們將用例方法歸類整理,便於後期修改維護時查找。
package com.shinerio.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SpecialMethod {
public String demand(); //描述方法用來實現的需求
public int id(); //方法編號
public String description() default "no description"; //方法描述
}
上面的自定義註解中我們使用到了demand,id,description三個註解元素,註解元素的可用類型如下:
- 8種基本數據類型(char,int,short,long,boolean,byte,double,float)
- String
- Class
- enum
- Annotation
- 以上類型的數據
使用非上述類型,編譯器會報錯,包裝類也是不被允許的,我們還發現註解可以作爲元素類型,也就是說我們可以通過這個來實現嵌套。
對於元素默認值,Java有嚴格的限制,元素不能存在不確定的值,即元素必須要麼在使用註解時明確提供值,要麼元素本身具有默認值,對於非基本類型的元素,null也不能作爲其值
下面我們來使用我們自定義的註解來標識一組用於四則運算的方法。
package com.shinerio.annotation;
public class Arithmetic {
@SpecialMethod(demand="arithmetical",id=1,description="addition")
public int add(int...num){
int sum = 0;
for (int i = 0; i < num.length; i++) {
sum+=num[i];
}
return sum;
}
@SpecialMethod(demand="arithmetical",id=2,description="subtraction")
public int sub(int rawNum,int...numForSubracted){
for (int i = 0; i < numForSubracted.length; i++) {
rawNum-=numForSubracted[i];
}
return rawNum;
}
}
使用註解的一個好處就是我們可以對註解進行解析,利用java的反射機制很容易幫助我們做到這一點
package com.shinerio.annotation;
import java.lang.reflect.Method;
public class AnnotationMenthodTracker {
public static void main(String[] args) {
Class<Arithmetic> c = Arithmetic.class;
for(Method m : c.getDeclaredMethods()){ //反射獲得類方法
SpecialMethod s = m.getAnnotation(SpecialMethod.class); //獲得加載此類上的註解
if(s!=null){ //若存在註解
System.out.println("需求是:"+s.demand()+",編號:"+s.id()
+",描述:"+s.description());
}
}
}
}
輸出:
需求是:arithmetical,編號:1,描述:addition
需求是:arithmetical,編號:2,描述:subtraction
當你看到這的時候是不是對你爲某個需求實現的方法一目瞭然呢!