1,什么是注解:
從JDK5開始,Java增加了對元數據 (MetaData)的支持,也就是Annotation注解,這種注解與注釋不一樣,注解其實是代碼里的特殊標記,這些標記可以在編譯、類加載 運行時被讀取並執行相應的處理。通過使用注解,程序開發人員可以在不改變原有邏輯的情況下,在源文件中嵌入一些補充的信息。代碼分析工具、開發工具和部署工具可以通過這些補充信息進行驗證或者進行部署。
注解提供了一種為程序元素設置元數據的方法,從某些方面來看,注解就像修飾符,可用於修飾包、類、構造器、方法、成員變量、參數、局部變量的聲明,這些信息被存儲在注解 "name=value"對中。
注解能被用來為程序元素(類、方法、成員變量等)設置元數據。值得指出的是,注解不影響程序代碼的執行,無論增加、刪除注解,代碼都始終如一地執,如果希望讓程序中的注解在運行時起一定的作用,只有通過某種配套的工具對注解中的信息進行訪問和處理,訪問和處理注解的工具統稱APT,也就是Annotation Processing Tool的縮寫。
2,Java5的常用的基本注解:
(1),重寫父類方法注解@Override:
該注解作用在一個方法上,告訴編譯器檢查該該方法是不是一個重寫父類的方法。這個注解的作用主要是為了幫助程序員屏蔽一些低級錯誤,比如,我們有一個方法叫做info,有的程序員可能就直接寫成了inf或者inf0,到時候排查的時候,也不太方便,如果在編譯的時候就能把這個錯誤報出來就是最好的。
子類重寫父類方法,請必須加@Override注解
(2),標記過時@Deprecated:
該注解也是作用在一個類或者方法上,表示一個類或者方法是不是已過時的,如果在其他程序里使用了已過時的類或者方法,編譯器會給出警告。
java9開始為Deprecated提供了兩個新的屬性:
- forRemoval: boolean 類型的屬性指定該API在將來是否會被刪除
- since: String 類型的屬性指定該API從哪個版本被標記為過時
(3),取消告警@SuppressWanings:
@SuppressWanings指示被該注解修飾的程序元素(以及該程序元素中的所有子元素)取消顯示指定的編譯器警告,@SuppressWanings一直作用於該程序元的所有子元素。
比如我們的集合框架如果沒有使用泛型就會造成編譯告警。不過V哥覺得,我們應該盡量不適用這個注解。我們應該解決掉程序開發中所有的告警。
(4),函數式接口@FunctionalInterface
自定義注解
元注解
元注解就是修飾注解的注解。java中定義了6個元注解。本節課我們先介紹常用的元注解。
1,@Retention
只能用於修飾注解定義,用於指定被修飾的注解的生命周期,
@Retention包含一個@RetentionPolicy類型的value成員變量,所以使用@Retention時必須為該value成員變量指定值。
value 成員變 的值只能是如下
- RetentionPolicy.CLASS: 編譯器將把注解記錄在class文件中,當運行Java程序時JVM不可獲取注解信息。這是默認值
- RetentionPolicy.RUNTIM: 編譯器將把注解記錄在class文件中,當運行 Java程序時JVM可獲取注解信息,程序可以通過反射獲取該注解信息
- RetentionPolicy.SOURCE: 注解只保留在源代碼中,編譯器直接丟棄這種注解
2,@Target
@Target 也只能修飾注解定義,
它用於指定被修飾的注解能用於修飾哪些程序單元@Target 元注解也包含一個名為 value 的成員變,該成員變量的值只能是如下幾個:
- ElementType.ANNOTATION_TYPE: 指定該策略的注解只能修飾注解。
- ElementType.CONSTRUCTOR: 定該策略的注解只能修飾構造器。
- ElementType.FIELD: 指定該策略的注解只能修飾成員變量。
- ElementType.LOCAL_VARIABLE: 定該策略的注解只能修飾局部變量
- ElementType.METHOD: 指定該策略的注解只能修飾方法定義。
- ElementType.PACKAGE: 指定該策略的注解只能修飾包定義。
- ElementType.PARAMETER: 指定該策略注解可修飾參數
- ElementType.TYPE: 定該策略的注解可以修飾類、接口(包括注解類型)或枚舉定義
3,@Documented
@Documented 用於指定被該元注解修飾的注解類將被javadoc工具提取成文檔,如果定義注解類時使用了@Documented修飾,則所有使用該注解修飾的程序元素的 API 文檔中將會包含該注解說明
4,@Inherited
@Inherited元注解指定被它修飾的注解將具有繼承性,如果某個類使用了@Xxx注解(定義該注解時使用了@Inherited修飾)修飾,則其子類將自動被@Xxx修飾。
創建注解
1,創建一個最簡單的注解
public @interface MyAnnotation { }
2,使用剛剛創建的注解:
@MyAnnotation public class MyClass { }
在默認情況下,注解可以修飾任何的程序元素,包括我們的類,接口,方法等等。所以我們定義的MyAnnotation注解,它可以修飾任何的程序元素。
3,帶成員變量的注解,成員變量在注解中的定義
以無參方法的形式來聲明
我們的注解的成員變量的類型,只能是基本數據類型和String,元數據類型,注解類型以及其對應的數組。
package com.zmd.myAnnotation; public @interface MyAnnotation { String name(); int age() ; }
如果添加了成員變量,那么使用的時候可以是如下格式:
package com.zmd.myAnnotation; @MyAnnotation(name = "hehe",age = 1) public class MyClass { }
4、還可以給注解的屬性加上默認值:
package com.zmd.myAnnotation; public @interface MyAnnotation { String name() default "zmd"; int age() default 22; }
如果加上了默認值之后,我們可以不對name和age賦值了。如果不復制,那么使用的就是默認值。