一、什麼是註解?
註解相當於一種標記,在程式中加了註解就等於為程式打上了某種標記,沒加,則等於沒有某種標記,以後,javac編譯器,開發工具和其他程式可以用反射來瞭解你的類及各種元素上有無何種標記,看你有什麼標記,就去幹相應的事。標記可以加在包,類,欄位,方法,方法的參數以及局部變數上。
看java.lang包,可看到JDK中提供的最基本的annotation。
@SuppressWarnings //消除警告
@Deprecated //不建議使用 、過時的
@Override //方法的重寫 注意public boolean equals(Objet other) 如果參數不是Object類型的,這是方法的重載!別大意。
二、註解的應用結構圖
註解就相當於一個你的來源程式中要調用的一個類,要在來源程式中應用某個註解,得先準備好了這個註解類。就像你要調用某個類,得先有開發好這個類。
三、自訂註解
1.定義一個最簡單的註解:public @interface MyAnnotation {}
- 把它加在某個類上:@MyAnnotation public class AnnotationTest{}
- 用反射進行測試AnnotationTest的定義上是否有@MyAnnotation
- 根據發射測試的問題,引出元註解@Retention元註解其三種取值:RetetionPolicy.SOURCE、RetetionPolicy.CLASS、RetetionPolicy.RUNTIME;分別對應:java源檔案-->class檔案-->記憶體中的位元組碼。
2.思考:@Override、@SuppressWarnings和@Deprecated這三個註解的屬性值分別是什嗎?
[RetetionPolicy.SOURCE、RetetionPolicy.SOURCE、RetetionPolicy.RUNTIME]
3.@Target元註解
Target的預設值為任何元素,設定Target等於ElementType.METHOD,原來加在類上的註解就報錯了,改為用數組方式設定{ElementType.METHOD,ElementType.TYPE}就可以了。
元註解以及其枚舉屬性值不用記,只要會看jdk提供那幾個基本註解的API協助文檔的定義或其原始碼,按圖索驥即可查到,或者直接看java.lang.annotation包下面的類。
三 、為註解增加屬性1.什麼是註解的屬性:註解是一種標識,註解的屬性是註解標識的內容。
加了屬性的標記效果為:@MyAnnotation(color="red")
定義基本類型的屬性和應用屬性:
- 在註解類中增加String color();
- @MyAnnotation(color="red")
2.用反射方式獲得註解對應的執行個體對象後,再通過該對象調用屬性對應的方法
MyAnnotation a = (MyAnnotation)AnnotationTest.class.getAnnotation(MyAnnotation.class);
System.out.println(a.color());
3.可以認為上面這個@MyAnnotation是MyAnnotaion類的一個執行個體對象
為屬性指定預設值:
- String color() default "yellow";
- value屬性:String value() default "zxx";
4.如果註解中有一個名稱為value的屬性,且你只想設定value屬性(即其他屬性都採用預設值或者你只有一個value屬性),那麼可以省略value=部分,例如:@MyAnnotation("lhm")。注意 :枚舉和註解都是特殊的類,不能用new 建立它們的執行個體對象,建立枚舉的執行個體對象就是在其中增加元素。在程式中如何建立出一個註解的執行個體對象啊?用@註解名代碼 :
public @interface MetaAnnotation//這是一個註解類{ String nextDay(); }
import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME) //保留到運行時--》這是元註解,註解的註解@Target({ElementType.METHOD,ElementType.TYPE})//可以查閱協助文檔-->ElementTypepublic @interface MyAnnotation//這是一個註解類{ String color() default "bule";//預設是 public abstract String value(); int[] arrayAttr() default {1,2,3};//數組屬性的註解類型 Class getCls() default String.class;//位元組碼屬性的註解類型 EnumTest.TrafficLamp lamp() default EnumTest.TrafficLamp.GREEN;//枚舉屬性的註解類型 MetaAnnotation annotationAttr() default @MetaAnnotation(nextDay="1月1號");//註解屬性的註解類型}
import java.util.Arrays;@MyAnnotation(color="red",value="3",arrayAttr={6,7,8},annotationAttr=@MetaAnnotation(nextDay="1月15號")) //這個類應用了註解類MyAnnotationpublic class AnnotationTest{ @SuppressWarnings("deprecation") //取消顯示指定的編譯器警告 @MyAnnotation("java")//只有一個屬性值,value= 可以省略不寫public static void main(String[] args) throws Exception{ //@SuppressWarnings("deprecation")加上註解後,編譯器不會警告System.runFinalizersOnExit(true);//這是一個過時的方法if(AnnotationTest.class.isAnnotationPresent(MyAnnotation.class)){ //利用反射得到AnnotationTest類的註解MyAnnotation annotation=(MyAnnotation)AnnotationTest.class.getAnnotation(MyAnnotation.class);System.out.println(annotation.color());System.out.println(annotation.value());System.out.println(Arrays.toString(annotation.arrayAttr()));System.out.println(annotation.lamp());System.out.println(annotation.annotationAttr().nextDay());}//利用反射擷取main方法的註解MyAnnotation annotation1=(MyAnnotation)AnnotationTest.class.getMethod("main", String[].class).getAnnotation(MyAnnotation.class);System.out.println(annotation1.color());//預設是blueSystem.out.println(annotation1.value());System.out.println(Arrays.toString(annotation1.arrayAttr()));System.out.println(annotation1.annotationAttr().nextDay());} @Deprecated public static void say() { System.out.println("hello world!"); }}