iT邦幫忙

2021 iThome 鐵人賽

DAY 30
0
自我挑戰組

Java SE系列 第 30

Day30:附魔

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種可以貼:

  • @Document,若有人貼上我們的Annotation,讓java doc可以顯示出來有貼上這個Annotation
  • @Retention,其內定義有enum RetentionPolicy:SOURCE, CLASS, RUNTIME
  • @Target,其內定義有enum ElementType,例如ElementType.TYPE, ElementType.METHOD等等,代表可以貼在什麼成員身上
  • @Inherited,預設標籤是不會繼承給子類別的,只有標註有@Inherited的標籤會傳承給子類別

針對@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;
}

上一篇
Day29:翻譯蒟蒻
系列文
Java SE30

尚未有邦友留言

立即登入留言