Java的註解非但是一種標記,還是一種特殊的類型,並且擁有專門的類型定義。前面介紹的五種內置註解,都可以找到對應的類型定義代碼,例如查看註解@Override的源碼,發現它的代碼定義是下麵這樣的: 又如註解@FunctionalInterface,它的源碼定義與之類似: 乍看過去,註解的定義竟與介面 ...
Java的註解非但是一種標記,還是一種特殊的類型,並且擁有專門的類型定義。前面介紹的五種內置註解,都可以找到對應的類型定義代碼,例如查看註解@Override的源碼,發現它的代碼定義是下麵這樣的:
@Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface Override {}
又如註解@FunctionalInterface,它的源碼定義與之類似:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface FunctionalInterface {}
乍看過去,註解的定義竟與介面有幾分相像,介面的類型名稱是“interface”,而註解的類型名稱是“@interface”,僅僅多了一個@符號。此外,內置註解的定義代碼上方多出了好幾個其它註解,包括@Target、@Retention、@Documented等等,這三個註解連同@Inherited組成了Java的“元註解”。四個元註解的作用是給新定義的註解添加修飾,標明新註解什麼能幹什麼不能幹,好比給一個戰士配備各式各樣的武器,使得他更適合在某種環境之中作戰。接下來就對四種元註解分別進行詳細介紹:
1、@Documented
該註解表示它修飾的註解將被收錄到Java的開發文檔中,這意味著程式員編碼時的快捷提示會出現已收入的註解。
所謂的快捷提示,指的是每當程式員輸入少數幾個字元並按下“Alt+/”時,eclipse就自動彈出以這幾個字元開頭的辭彙列表,以便程式員迅速選擇想要的辭彙,從而加快編碼速度。比如,程式員在某個空行輸入字母M,然後按下組合鍵“Alt+/”,eclipse會彈出以M打頭的辭彙列表,包括數學函數庫Math、映射Map、方法Method等等,此時點擊“Method”這行提示,eclipse便自動把M補齊成為Method。
添加了@Documented的註解如@FunctionalInterface,就會出現在這種提示列表;而@Override沒被@Documented所修飾,就不會在提示列表中出現。故而程式員在一個空行輸入符號@,然後按下組合鍵“Alt+/”,彈出的辭彙列表中能找到“@FunctionalInterface”,卻不能找到“@Override”了。
2、@Target
該註解表示它修飾的註解將作用於哪一類的代碼實體,例如ElementType.METHOD規定@Override對方法有效,而ElementType.TYPE規定@FunctionalInterface對類型有效。更多的ElementType取值說明見下:
TYPE:類型,包括類、介面和枚舉。
FIELD:欄位,即類的屬性。
METHOD:方法,但不包含構造方法。
PARAMETER:方法的參數。
CONSTRUCTOR:構造方法。
LOCAL_VARIABLE:局部變數。
ANNOTATION_TYPE:註解類型。
PACKAGE:包。
3、@Retention
該註解表示它修飾的註解將被編譯器保留至哪個階段,例如“@Retention(RetentionPolicy.SOURCE)”規定編譯器只在編碼階段保留@Override,而“@Retention(RetentionPolicy.RUNTIME)”規定編譯器直到運行階段仍然保留@FunctionalInterface。更多的RetentionPolicy取值說明見下:
SOURCE:只在編碼階段保留。
CLASS:保留在編譯生成的class文件中,但不在運行時保留。這樣從class文件反編譯出來的源碼仍可找到它所修飾的註解。
RUNTIME:一直保留至運行階段。這樣修飾後的註解可通過反射技術讀取獲得,以便代碼在運行時動態校驗註解。
4、@Inherited
該註解表示它修飾的註解將允許被子類所繼承。
通常情況下,一個註解加在某個類上面的話,它只對當前類有效,而對當前類的子類無效。倘若程式員希望該註解同時作用於當前類及其所有子類,則需要給這個註解的定義代碼添加@Inherited修飾,表示該註解的作用範圍擴展到當前類派生出來的子類。
更多Java技術文章參見《Java開發筆記(序)章節目錄》