Annotation,大概最常見的就是@Override了,當我們寫的類別繼承自其他類別時,要覆寫父類別的方法,假設不小心打錯父類別方法的名稱,或者參數、返回型態不一致,那@Override就會在IDE或者編譯時期告訴我們這個方法可能沒有覆寫到父類別的方法哦~(因為父類別沒有同樣簽章的方法)。
這個Annotation我們也可以自己寫,首先要先這樣:
public @interface CustomAnnotation { }
很像定義介面,不過interface前面要加個"@"。
然後我們可以幫它加屬性:
public @interface CustomAnnotation {
String value();
String[] author() default "";
}
屬性後面不像定義類別,需要多加"()",可以往setter和getter的感覺想像吧!
如果我們定義有value的屬性,那它在單獨指派時可以直接指派值,不需要先寫出屬性名稱後再打"=";可以看到author屬性後面寫了關鍵字default,這就代表是預設的屬性值,假若Annotation在定義的時候屬性沒有給預設值,那使用時就必須給那個屬性值:
public class Student{
@CustomAnnotation(value = "Midterm")
public void doTest(){}
@CustomAnnotation("Final")
public void doTest2(){}
@CustomAnnotation(value = "Pickup", author={"Johnny", "Andy"})
public void haveFun(){}
}
因為@CustomeAnnotation的value沒有預設值,勢必都要指派value屬性的值過去,而author屬性可以不指派,那就是預設的""。
Annotation的屬性型別是有限制的,只能是primitive, String, Class, enum, annotation及其陣列型式:
public @interface CustomAnnotation {
publci enum Difficulty{EASY, MEDIUM, HARD}
String value();
String[] author() default "";
Difficulty difficulty() default Difficulty.EASY;
}
Annotation除了可以貼在其他人身上,自己身上也可以貼Annotation,不過只有4種可以貼:
針對@Retention多說明一點,Java預設是RetentionPolicy.CLASS,代表說在編譯時期結束後會保留在.class檔案,但是執行時期無法取用;而RetentionPolicy.SOURCE代表編譯時期會取用,但編譯完不會存成.class檔案;而RetentionPolicy.RUNTIME就代表執行時期也可以透過java.lang.reflect.AnnotatedElement套件的功能取用到Annotation的屬性內容:
public static void main(String[] args){
Student student0 = new Student();
Method doTest = student0.getClass().getMethod("doTest");
CustomAnnotation ca = doTest.getAnnotation(CustomAnnotation.class);
ca.value();
ca.author();
ca.difficulty();
}
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation {
publci enum Difficulty{EASY, MEDIUM, HARD}
String value();
String[] author() default "";
Difficulty difficulty() default Difficulty.EASY;
}