上一篇文章我們講了註解的前兩個:1.內置的註解 2.自定義註解 ,再回顧一下知識:
註解是Java的一種機制,允許開發人員向代碼的不同部分附加信息,它並不是代碼的一部分,因爲它不會修改代碼在運行時的行爲,不會修改代碼的語義。它主要用於對方法是否依賴方法、方法是否完整,類是否引用了其他類等給出提示信息幫助你編寫正確代碼。
分類:
1.內置的註解
2.自定義註解
3.爲註解添加的註解
接下來繼續接着講剩下的內容:
三.爲註解添加的註解
分類:
(1)Target
(2)Retention
(3)Documented
(4)Inherited
下面將分別進行介紹:
1.@Target
作用:用於指定代碼中的哪些元素可以使用已定義類型的註解。
語法示例:
@Target(ElementType.METHOD)//指定Task註解只能用於方法
@interface Task{
String description();
}
除了ElementType.METHOD外,還可以指定以下類型及其作用:
ElementType.TYPE:可以應用於類的任何元素。
ElementType.FIELD:可以應用於字段(數據成員)。
ElementType.PARAMETER:可以應用於方法參數。
ElementType.CONSTRUCTOR:可以應用於構造函數。
ElementType.LOCAL_VARIABLE:可以應用於局部變量。
ElementType.ANNOTATION_TYPE:指出聲明的類型本身是註解類型,即可以應用於註解類型。
2.@Retention
作用:用於設置註解的可見性。
可見性分爲三個級別:編譯器可見、工具可見、運行時可見
語法示例:
@Retention(RetentionPolicy.RUNTIME)
@interface Task{
}
其中RetentionPolicy枚舉(用來設置註解的可見性)定義了三個常量:SOURCE、CLASS和RUNTIME,
(1)SOURCE:註解對編譯器可見,對.class文件和運行時不可見。編譯器可用此註解來檢測錯誤和抑制警告,使用完後會丟棄註解。
(2)CLASS:註解對.class文件可見。
(3)RUNTIME:註解對.class文件和運行時可見。
運行時註解RUNTIME示例:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
@WorkInProgress
public class RuntimeAnnotation {
@WorkInProgress
@Task(description="Implement tax",
estimatedHours=50,
additionalNote="This implement")
public static float computeTax(float amount,float rate){
return 0;
}
public static void main(String[]args){
try{
RuntimeAnnotation obj=new RuntimeAnnotation();
Class cls=obj.getClass();//返回對RuntimeAnnotation這個Class對象的引用
WorkInProgress wkAnnotation=(WorkInProgress)cls.getAnnotation(WorkInProgress.class);//獲取WorkInProgress類型的註解,如果找不到則返回null
System.out.println("Class:"+cls.getName());
//檢查cls這個元素(類)是否有註解
if(cls.isAnnotationPresent(WorkInProgress.class)){
System.out.println("\tThis class is not fully implemented.");
}
System.out.println("List of methods:");
Method[]methods=cls.getMethods();//內省對象cls,反射獲取它的所有方法
for(Method method:methods){
System.out.println(method.getName());
if(method.isAnnotationPresent(WorkInProgress.class)){
System.out.println("\tThis method is not fully implemented.");
}
if(method.isAnnotationPresent(Task.class)){
Task tsAnnotation=(Task)method.getAnnotation(Task.class);
System.out.println(tsAnnotation.description()+" "+
tsAnnotation.targetDate()+" "+
tsAnnotation.estimatedHours()+" "+
tsAnnotation.additionalNote());
}
}
}
catch(Exception e){
e.printStackTrace();
}
}
}
//以下是兩個自定義的註解
@Retention(RetentionPolicy.RUNTIME)//設置註解的可見性是 運行時可見
@interface WorkInProgress{
}
@Retention(RetentionPolicy.RUNTIME)
@interface Task{
String description();
String targetDate() default "Jan 1,2012";
int estimatedHours();
String additionalNote();
}
運行結果:
Class:TestAnnotation.RuntimeAnnotation
This class is not fully implemented.
List of methods:
main
computeTax
This method is not fully implemented.
Implement tax Jan 1,2012 50 This implement
wait
wait
wait
equals
toString
hashCode
getClass
notify
notifyAll
3.@Documented
作用:表示javadoc工具應該爲帶有這種類型的註解生成文檔。它是一種Marker類型的註解,沒有任何成員。
注:javadoc是JDK中包含的文檔生成器,用於從Java源代碼生成HTML格式的API文檔。
例如我爲前面的WorkInProgress和Task兩個註解前都加上@Documented註解之後,使用javadoc工具爲RuntimeAnnotation.java文件生成API文檔後打開查看ComputeTax方法,結果如下:
可以看到,兩個註解WorkInProgress和Task都有對應的文檔。
4.@Inherited
當子類繼承父類時,在默認情況下時不會繼承父類的註解的,而使用@Inherited對父類的註解進行註解後,子類會繼承父類的註解。
例如:
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@interface WorkInProgress{
}
然後RuntimeAnnotation父類使用了WorkInProgress的註解:
@WorkInProgress
public class RuntimeAnnotation {
接着使用子類RunAnnotation繼承父類RuntimeAnnotation:
public class RunAnnotation extends RuntimeAnnotation{
此時子類RunAnnotation繼承父類RuntimeAnnotation的註解WorkInProgress。