文章目錄
- 註解(Annotation)簡介
- 元註解
- 註解的生命週期
- 註解的定義
- 註解的使用
- 程式碼範例:
- 總結
註解(Annotation)簡介
Annotation(註解)是JDK5.0 及以後版本引入的一個特性。註解是java 的一個新的類型(與介面很相似),它與類、介面、枚舉是在同一個層次,它們都稱作為java 的一個類型(TYPE)。它可以聲明在包、類、欄位、方法、局部變數、方法參數等的前面,用來對這些元素進行說明,注釋。它的作用非常的多,例如:進行編譯檢查、產生說明文檔、程式碼分析等。
JDK提供的幾個基本註解a. @SuppressWarnings
該註解的作用是阻止編譯器發出某些警告資訊。
它可以有以下參數:
deprecation:過時的類或方法警告。
unchecked:執行了未檢查的轉換時警告。
fallthrough:當Switch 程式塊直接通往下一種情況而沒有Break 時的警告。
path:在類路徑、源檔案路徑等中有不存在的路徑時的警告。
serial:當在可序列化的類上缺少serialVersionUID 定義時的警告。
finally:任何finally 子句不能完成時的警告。
all:關於以上所有情況的警告。
b. @Deprecated
該註解的作用是標記某個過時的類或方法。
c. @Override
該註解用在方法前面,用來標識該方法是重寫父類的某個方法。
元註解a. @Retention
它是被定義在一個註解類的前面,用來說明該註解的生命週期。
它有以下參數:
RetentionPolicy.SOURCE:指定註解只保留在一個源檔案當中。
RetentionPolicy.CLASS:指定註解只保留在一個class 檔案中。
RetentionPolicy.RUNTIME:指定註解可以保留在程式運行期間。
b. @Target
它是被定義在一個註解類的前面,用來說明該註解可以被聲明在哪些元素前。
它有以下參數:
ElementType.TYPE:說明該註解只能被聲明在一個類前。
ElementType.FIELD:說明該註解只能被聲明在一個類的欄位前。
ElementType.METHOD:說明該註解只能被聲明在一個類的方法前。
ElementType.PARAMETER:說明該註解只能被聲明在一個方法參數前。
ElementType.CONSTRUCTOR:說明該註解只能聲明在一個類的構造方法前。
ElementType.LOCAL_VARIABLE:說明該註解只能聲明在一個局部變數前。
ElementType.ANNOTATION_TYPE:說明該註解只能聲明在一個註解類型前。
ElementType.PACKAGE:說明該註解只能聲明在一個包名前。
註解的生命週期
一個註解可以有三個生命週期,它預設的生命週期是保留在一個CLASS 檔案,但它也可以由一個@Retetion 的元註解指定它的生命週期。
a. java 源檔案
當在一個註解類前定義了一個@Retetion(RetentionPolicy.SOURCE)的註解,那麼說明該註解只保留在一個源檔案當中,當編譯器將源檔案編譯成class 檔案時,它不會將源檔案中定義的註解保留在class 檔案中。
b. class 檔案中
當在一個註解類前定義了一個@Retetion(RetentionPolicy.CLASS)的註解,那麼說明該註解只保留在一個class 檔案當中,當載入class 檔案到記憶體時,虛擬機器會將註解去掉,從而在程式中不能訪問。
c. 程式運行期間
當在一個註解類前定義了一個@Retetion(RetentionPolicy.RUNTIME)的註解,那麼說明該註解在程式運行期間都會存在記憶體當中。此時,我們可以通過反射來獲得定義在某個類上的所有註解。
註解的定義
一個簡單的註解:
public @interface Annotation01 {
//定義公用的final靜態屬性
.....
//定以公用的抽象方法
......
}
a. 註解可以有哪些成員
註解和介面相似,它只能定義final 靜態屬性和公用抽象方法。
b. 註解的方法
1.方法前預設會加上public abstract
2.在聲明方法時可以定義方法的預設傳回值。
例如:
String color() default "blue";
String[] color() default {"blue", "red",......}
3.方法的傳回值可以有哪些類型
8 種基本類型,String、Class、枚舉、註解及這些類型的數組。
c. 使用註解(參照下面的註解使用)註解的使用
註解的使用分為三個過程。
定義註解-->聲明註解-->得到註解
a. 定義註解(參照上面的註解定義)b. 聲明註解
1. 在哪些元素上聲明註解
如果定義註解時沒有指定@Target 元註解來限制它的使用範圍,那麼該註解可以使用在ElementType 枚舉指定的任何一個元素前。否則,只能聲明在@Target 元註解指定的元素前。
一般形式:
@註解名()
2. 對註解的方法的傳回值進行賦值
對於註解中定義的每一個沒有預設傳回值的方法,在聲明註解時必須對它的每一個方法的傳回值進行賦值。
一般形式:
@註解名(方法名=方法傳回值,、、、、、、)
如果方法返回的是一個數組時,那麼將方法傳回值寫在{}符號裡
@註解名(方法名={傳回值1,傳回值2,、、、、、、},、、、、、、、)
3. 對於只含有value 方法的註解,在聲明註解時可以唯寫傳回值。
c. 得到註解
對於生命週期為運行期間的註解,都可以通過反射獲得該元素上的註解執行個體。
1、聲明在一個類中的註解
可以通過該類Class 對象的getAnnotation 或getAnnotations 方法獲得。
2、聲明在一個欄位中的註解
通過Field 對象的getAnnotation 或getAnnotations 方法獲得
3、聲明在一個方法中的註解
通過Method 對象的getAnnotation 或getAnnotations 方法獲得
程式碼範例:
1 package Test_annotation; 2 3 import java.lang.reflect.Method; 4 5 public class Test_1 { 6 /* 7 * 被註解的三個方法 8 */ 9 @Test(id = 1, description = "hello method_1")10 public void method_1() {11 }12 13 @Test(id = 2)14 public void method_2() {15 }16 17 @Test(id = 3, description = "last method")18 public void method_3() {19 }20 21 /*22 * 解析註解,將Test_1類 所有被註解方法 的資訊列印出來23 */24 public static void main(String[] args) {25 Method[] methods = Test_1.class.getDeclaredMethods();26 for (Method method : methods) {27 /*28 * 判斷方法中是否有指定註解類型的註解29 */30 boolean hasAnnotation = method.isAnnotationPresent(Test.class);31 if (hasAnnotation) {32 /*33 * 根據註解類型返回方法的指定類型註解34 */35 Test annotation = method.getAnnotation(Test.class);36 System.out.println("Test( method = " + method.getName()37 + " , id = " + annotation.id() + " , description = "38 + annotation.description() + " )");39 }40 }41 }42 43 }
列印輸出結果:
| Test( method = method_1 , id = 1 , description = hello method_1 ) Test( method = method_2 , id = 2 , description = no description ) Test( method = method_3 , id = 3 , description = last method ) |
總結
註解可以看成是一個介面,註解執行個體就是一個實現了該介面的動態代理類。註解大多是用做對某個類、方法、欄位進行說明,標識的。以便在程式運行期間我們通過反射獲得該欄位或方法的註解的執行個體,來決定該做些什麼處理或不該進行什麼處理。