愉快地學Java語言:第十八章 註解

導讀

本文適合Java入門,不太適合Java中高級軟件工程師。本文以《Java核心技術》第10版為藍本,採用不斷提出問題,然後解答問題的方式來講述。本篇文章只是這個系列中的一篇,如果你喜歡這種講解方式,或者覺得從中能學到知識,可以關注我,以便查閱本系列其他文章。

愉快地學Java語言:第十八章 註解

讓我們開始愉快地學習Java語言吧!

1註解簡介

註解是什麼?

從語法角度講,註解是一種接口,而且是一種特殊的接口。

為什麼說註解是一種特殊的接口,特殊在哪裡?

都隱式擴展自java.lang.annotation.Annotation接口;

不能泛型化;

不能擴展註解(接口);

只能定義沒有參數的方法,且方法的返回類型是有限制的,也不能定義會拋出異常的方法,方法可以有一個默認返回值。

註解有什麼作用?

可以使用註解修飾類、類的成員、局部變量等,以便提供額外的信息。會提供什麼樣的額外信息呢?概括來講,無法在一般程序代碼中體現的信息,都可以使用註解來表達。

2註解語法

修飾符 @interface 註解名稱{

類型 方法名();

...

}

1)方法可以有默認的返回值,定義形式為:

類型 方法名() default 默認值;

2)上面提到方法返回值類型是有限制的,那麼什麼樣的類型可以作為方法返回值呢?

以下類型都可:基本類型、String、Class、枚舉、註解

由上面那些類型構成的數組

3)我們稱註解中定義的方法為元素。使用下面的形式,每個註解可以包含多個元素。

@註解名稱(元素名稱=value1,...,元素名稱=value2,)

4)註解元素的順序任意,因為是根據鍵值對的形式來識別註解元素的。

5)如果定義了某個元素,但是使用的時候沒給他賦值,那麼就使用默認值。

6)默認值不是和註解存儲在一起,這有什麼好處呢?

如果你修改了註解的默認值,然後重新編譯,那麼對於使用了這些註解的代碼來說,不用重新編譯這部分代碼,他們也會使用修改後的默認值,所以這個默認值是動態變化的。

7)如果註解沒有定義任何方法或者使用註解時元素都為默認值,可簡化為:@註解名稱,我們稱之為標記註解,@Override就是標記註解。

8)如果一個註解只有一個方法且方法名為value,我們稱之為單值註解,使用時可以簡化為:@註解名稱(value1)

9)使用註解時,所有元素值必須是編譯期常量。

10)註解元素的默認值不能是null,使用註解時也不能給元素賦null

11)元素類型為數組,那麼賦值時要使用大括號表示數組。

12)可以用多個註解修飾一個目標

13)可以多次重複使用一個註解,但前提定義註解的時候是要聲明為可重複

3註解出現的位置

註解可以修飾:包、類、接口、方法、構造器、實例域、局部變量、參數變量、類型參數、枚舉、枚舉常量。

1)修飾類、接口、修飾方法、構造器、實例域

位於各個修飾符的最前面

2)修飾變量(局部變量、參數變量)

位於類型前

3)修飾類型參數

位於類型參數前

4 Java SE提供的註解

4.1元註解

元註解是可以修飾一個註解的註解。

愉快地學Java語言:第十八章 註解

@Target

看下面註解Override的實現中使用了@Target;然後我們看下@Target的實現,發現它只定義一個元素value,並且它還使用了自身。這種“註解自己修飾自己”很有意思。通過給value賦值就可以限制其可修飾的元素,譬如,@Override的@Target使用ElementType.METHOD,表明@Override只能用來修飾方法,而@Target的@Target使用ElementType.ANNOTATION_TYPE,表明其只能用來修飾註解

愉快地學Java語言:第十八章 註解

愉快地學Java語言:第十八章 註解

有必要將ElementType的每個值,因此我列了個表格

愉快地學Java語言:第十八章 註解

@Retention

看下面@Retention的定義,它只定義了一個元素value,它的返回值類型為RetentionPolicy,通過為value賦值來設置註解保留策略。

愉快地學Java語言:第十八章 註解

愉快地學Java語言:第十八章 註解

我們來寫一個例子觀察下,這個註解的作用

愉快地學Java語言:第十八章 註解

愉快地學Java語言:第十八章 註解

愉快地學Java語言:第十八章 註解

使用反射檢測一下類AnnUsing是否使用了CustomAnn修飾,代碼及執行結果如上,發現沒有檢測到CustomAnn,但是我已明確使用CustomAnn註解修飾AnnUsing類了,為啥調用isAnnotationPresent返回值為false呢?

如果我們在CustomAnn上添加@Retention(RetentionPolicy.RUNTIME),那麼在調用isAnnotationPresent,其返回值為true

@Documented

上面對@Documented的說明比較抽象,下面我們來實踐一下,看看到底會有啥現象。

愉快地學Java語言:第十八章 註解

愉快地學Java語言:第十八章 註解

讓我們使用javadoc命令生成文檔看看,注意選擇適當的編碼以防中文亂碼

愉快地學Java語言:第十八章 註解

打開/home/doc/index.html,看下頁面顯示

愉快地學Java語言:第十八章 註解

如果將上述自定義註解中的@Documented去掉,生成文檔如下

愉快地學Java語言:第十八章 註解

可以發現,使用@Documented修飾CustomAnn,那麼使用CustomAnn修飾AnnUsing,生成的文檔中會顯示出AnnUsing這個類被CustomAnn這一註解修飾。

@Inherited

看一個例子,演示下這個註解的作用。

愉快地學Java語言:第十八章 註解

愉快地學Java語言:第十八章 註解

愉快地學Java語言:第十八章 註解

愉快地學Java語言:第十八章 註解

由上面結果可以看出子類Child也被@CustomAnn修飾,雖然我沒有將@CustomAnn寫在Child類上。如果將@Inherited去掉,那麼isAnnotationPresent返回值為false。

4.2用於編譯的註解

愉快地學Java語言:第十八章 註解

@Deprecated

定義如下,可以看出其可以應用於:

愉快地學Java語言:第十八章 註解

愉快地學Java語言:第十八章 註解

@SuppressWarnings

定義如下,可以看出其適用範圍和@Deprecated差不多,只是不能用於包聲明。它定義了一個元素value,代表抑制警告的類型,那麼都有哪些類型呢?

愉快地學Java語言:第十八章 註解

愉快地學Java語言:第十八章 註解

注,這些關鍵字的英文釋義參見網址:

https://help.eclipse.org/kepler/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Ftasks%2Ftask-suppress_warnings.htm

愉快地學Java語言:第十八章 註解

@Generated

這個註解是給代碼生成工具使用的,也就是說,不一定所有代碼都是我們一個字符一個字符地敲上去的,也可以用代碼生成工具自動生成一段代碼,為了按照一定規則生成代碼,我們可以使用這個註解,凡是被這個註解標註的部分都可以用代碼生成工具生成。

4.3 用於管理資源的註解

愉快地學Java語言:第十八章 註解


你還可以看看往期文章:


分享到:


相關文章: