jdk1.5之後,引入了中繼資料的概念,也就是annotation(注釋),其實它是代碼裡的特殊标記,這些标記可以再編譯、類加載、運作時被讀取,并執行相應的處理。
中繼資料的作用:
如果要對于中繼資料的作用進行分類,目前還沒有明确的定義,不過我們可以根據它所起的作用,大緻可分為三類:
1. 編寫文檔:通過代碼裡辨別的中繼資料生成文檔。
2. 代碼分析:通過代碼裡辨別的中繼資料對代碼進行分析。
3. 編譯檢查:通過代碼裡辨別的中繼資料讓編譯器能實作基本的編譯檢查。
一、 系統内建的annotation:
@override 覆寫的annotation
注釋能實作編譯時檢查,你可以為你的方法添加該注釋,以聲明該方法是用于覆寫父類中的方法。如果該方法不是覆寫父類的方法,将會在編譯時報錯。例如我們為某類重寫tostring()方法卻寫成了tostring(),并且我們為該方法添加了@override注釋,則會提示編譯錯誤。
@deprecated 不贊成使用的annotation
其作用是對不應該在使用的方法添加注釋,當程式設計人員使用這些方法時,将會在編譯時顯示提示資訊,不推薦在使用該方法或該類。
@suppresswarnings 壓制安全警告的annotation
與前兩個注釋有所不同,你需要添加一個參數才能正确使用,這些參數值都是已經定義好了的,我們選擇性的使用就好了,參數如下:
deprecation 使用了過時的類或方法時的警告
unchecked 執行了未檢查的轉換時的警告,例如當使用集合時沒有用泛型 (generics) 來指定集合儲存的類型
fallthrough 當 switch 程式塊直接通往下一種情況而沒有 break 時的警告
path 在類路徑、源檔案路徑等中有不存在的路徑時的警告
serial 當在可序列化的類上缺少 serialversionuid 定義時的警告
finally 任何 finally 子句不能正常完成時的警告
all 關于以上所有情況的警告
在為@suppresswarnings設定注釋資訊的時候,是以key-value的形式出現的,是以以上的@suppresswarnings也可以直接使用,是以@suppresswarnings可以使用”value={"unchecked","deprecation"}“的方式來設定。
上面,我們将 注釋掉,編譯後,會出現警告提示:
---------- javac ----------
注: suppresswarningsannotationdemo03.java使用或覆寫了已過時的 api。
注: 有關詳細資訊, 請使用 -xlint:deprecation 重新編譯。
注: suppresswarningsannotationdemo03.java使用了未經檢查或不安全的操作。
注: 有關詳細資訊, 請使用 -xlint:unchecked 重新編譯。
打開@suppresswarnings注釋,再次編譯,發現,警告已被抑制。
二、 自定義annotation
定義簡單的annotation形式:
[public] @interface annotation名稱{
資料類型 變量名稱();
}
例如:
之後,就可以直接使用@annotation名稱:
此時,就表示在demo類上使用annotation。
還可以向annotation中設定變量,使用變量接受參數。
在使用的時候,必須清楚的指定變量的名稱,變量的内容:
或者使用明确的标記,表示内容賦給哪個參數:
以上的參數,是要賦給value屬性的。既然可以設定一個參數,則也就可以同時設定多個參數。
此annotation在使用時,需要設定兩個參數,一個key,一個value。
當然,我們可以設定數組進去,@suppresswarnings就使用了數組。
接收内容本身是一個數組類型,要傳遞數組。
以上的定義annotation都未指定屬性的預設值,必須在使用時設定。 其實,也可以直接使用default來定義預設值:
在實際的操作中,對于一個annotation而言,有時候會固定其取值範圍,隻能使用固定的幾個值。那麼這時候實際上就需要依靠枚舉:
三、 限定注釋使用範圍target
當我們的自定義注釋不斷的增多也比較複雜時,就會導緻有些開發人員使用錯誤,主要表現在不該使用該注釋的地方使用。為此,java提供了一個elementtype枚舉類型來控制每個注釋的使用範圍,比如說某些注釋隻能用于普通方法,而不能用于構造函數等。下面是java定義的elementtype枚舉:
想要使用elementtype,隻需要為注釋添加@target即可:
正如上面代碼所展示的,我們隻允許greeting注釋标注在普通方法和構造函數上,使用在包申明、類名等時,會提示錯誤資訊。
四、 retention和retentionpolicy,注釋保持性政策
retentionpolicy的使用方法的簡單代碼示例如下:
@retention(retentionpolicy.runtime)
而,在retentionpolicy的三個範圍中,最需要注意的就是runtime範圍,因為在執行的時候起作用。
我們看下内建的annotation的retentionpolicy:
@override定義采用的是@retention(value=source),隻能在源檔案中出現。
@deprecated定義采用的是@retention(value=runtime),可以在執行時出現。
@suppresswarnings定義采用的是@retention(value=source),隻能在源檔案中出現。
五、 文檔化功能
java提供的documented元注釋跟javadoc的作用是差不多的,其實它存在的好處是開發人員可以定制javadoc不支援的文檔屬性,并在開發中應用。它的使用跟前兩個也是一樣的,簡單代碼示例如下:
成功後,在使用此annotation的時候,可以增加一些資訊進去:
之後,在生成jdk文檔的時候,使用@document修飾的方法将被注釋下來。
六、 标注繼承
繼承應該是java提供的最複雜的一個元注釋了,它的作用是控制注釋是否會影響到子類(一個annotation是否可以被繼承下來),簡單代碼示例如下:
使用該注釋,标注一個父類person:
按照所解釋的,使用inherited聲明的annotation是可以被子類繼承下來的: