JDK5--Annotation学习:基础(一)
轉(zhuǎn)載連接:http://www.iteye.com/topic/165316
背景知識:
?????? 從JDK5開始提供名為Annotation(注釋)的功能,它被定義為JSR-175規(guī)范。注釋是以“@注釋名”在代碼中存在的,還可以添加一些參數(shù)值,例如:@SuppressWarnings(value="unchecked")。注釋可以附加在package, class, method, field等上面,相當(dāng)于給它們添加了額外的輔助信息,我們可以通過反射機(jī)制編程實現(xiàn)對這些元數(shù)據(jù)的訪問。如果沒有外部解析工具等對其加以解析和處理的情況,本身不會對Java的源代碼或class文件等產(chǎn)生任何影響,也不會對它們的執(zhí)行產(chǎn)生任何影響。
???? 元數(shù)據(jù)的作用,大致可分為三種:編寫文檔,通過代碼里標(biāo)識的元數(shù)據(jù)生成文檔;代碼分析,通過代碼里標(biāo)識的元數(shù)據(jù)對代碼進(jìn)行分析;編譯檢查,通過代碼里標(biāo)識的元數(shù)據(jù)讓編譯器能實現(xiàn)基本的編譯檢查。
JDK5內(nèi)置的基本注釋
??? JDK5內(nèi)置了一些常用的注釋,可以在編譯時幫我們捕獲部分編譯錯誤,及提示信息,下面介紹下這些注釋的用法:
1、@Override定義在java.lang.Override中,此注釋只適用于修辭方法,表示一個方法聲明打算重寫超類中的另一個方法聲明。如果方法利用此注釋類型進(jìn)行注解但沒有重寫超類方法,則編譯器會生成一條錯誤消息。例如我們?yōu)槟愁愔貙憈oString()方法卻寫成了tostring(),并且我們?yōu)樵摲椒ㄌ砑恿?#64;Override注釋;代碼如下:
?
public class OverrideDemo {@Override public String tostring() {return super.toString();} }
在編譯時,會提示以下錯誤信息:
??????? @Override
???????? ^1 錯誤
2、@Deprecated定義在java.lang.Deprecated中,此注釋可用于修辭方法、屬性、類,表示不鼓勵程序員使用這樣的元素,通常是因為它很危險或存在更好的選擇。在使用不被贊成的程序元素或在不被贊成的代碼中執(zhí)行重寫時,編譯器會發(fā)出警告。使用@Deprecated的示例代碼如下:
在編譯時,會得到以下提示信息:
注意:要了解詳細(xì)信息,請使用 -Xlint:deprecation 重新編譯。
如果在編譯時添加-Xlint:deprecation參數(shù),我們能更清楚的看到該警告的詳細(xì)信息,如下:
??????????????? SomeClass.DeprecatedMethod();
???????????????????????? ^1 警告
要注意@Deprecated與@deprecated的區(qū)別,@deprecated是為了生成文檔的需要,例如:
3、@SuppressWarnings定義在java.lang.SuppressWarnings中,用來抑制編譯時的警告信息。與前兩個注釋有所不同,你需要添加一個參數(shù)才能正確使用,這些參數(shù)值都是已經(jīng)定義好了的,我們選擇性的使用就好了,參數(shù)如下:
通過上面的表格,你應(yīng)該了解到每個參數(shù)的用意了,下面我就以一個常用的參數(shù)unchecked為例,為你展示如何使用@SuppressWarnings注釋,示例代碼如下:
當(dāng)我們不使用@SuppressWarnings注釋時,編譯器就會有如下提示:
注意:要了解詳細(xì)信息,請使用 -Xlint:unchecked 重新編譯。
下面我們?nèi)サ?#64;SuppressWarnings(value="unchecked")這一行的注釋符“//”,它會屏蔽編譯時的警告信息,這也就是它所要達(dá)到的目的。
????? 另外,由于@SuppressWarnings注釋只有一個參數(shù),并且參數(shù)名為value,所以我們可以將上面一句注釋簡寫為
@SuppressWarnings("unchecked");
同時參數(shù)value可以取多個值如:
@SuppressWarnings(value={"unchecked", "deprecation"})
或@SuppressWarnings({"unchecked", "deprecation"})。
自定義Annotation注釋
1、注釋annotation與接口的異同:
因為annotation類型是一個非凡的接口,所以它與接口之間存在著某些差異:
A. Annotation類型使用關(guān)鍵字@interface而不是interface,這個關(guān)鍵字聲明隱含了一個信息,它是繼承了java.lang.annotation.Annotation接口,并非聲明了一個interface。
B. Annotation類型的方法定義是獨(dú)特的、受限制的,方法必須聲明為無參數(shù)、無異常拋出的。這些方法定義了annotation的成員:方法名成為了成員名,而方法返回值成為了成員的類型。而方法返回值類型必須為primitive類型、Class類型、枚舉類型、annotation類型或者由前面類型之一作為元素的一維數(shù)組。方法的后面可以使用default和一個默認(rèn)數(shù)值來聲明成員的默認(rèn)值,null不能作為成員默認(rèn)值,這與我們在非annotation類型中定義方法有很大不同。
C. Annotation類型又與接口有著近似之處,它們可以定義常量、靜態(tài)成員類型(比如枚舉類型定義)。Annotation類型也可以如接口一般被實現(xiàn)或者繼承。
2、自定義注釋的實例:
下面,我們將看到如何定義annotation類型的例子。它展示了annotation類型聲明以及
下面的另一個例子只定義了一個成員。并通過將這個成員命名為value,使我們可以方便的使用這種annotation的快捷聲明方式:
以下的例子更加復(fù)雜。Reviews annotation類型只有一個成員,但是這個成員的類型是復(fù)雜的:由Review annotation組成的數(shù)組。Review annotation類型有3個成員:枚舉類型成員grade、表示Review名稱的字符串類型成員Reviewer、具有默認(rèn)值的字符串類型成員 Comment。
最后,我們來定義一個annotation方法用于羅列出類運(yùn)行中所有的unchecked異常。這個 annotation類型將一個數(shù)組作為了唯一的成員。數(shù)組中的每個元素都是異常類。為了加強(qiáng)對未檢查的異常(此類異常都是在運(yùn)行時拋出)進(jìn)行報告,我們可以在代碼中對異常的類型進(jìn)行限制:
?
public @interface UncheckedExceptions { Class[] value(); }
Meta-Annotation類型:
Annotation 類型可以被它們自己所標(biāo)注。Java5.0定義了4個標(biāo)準(zhǔn)的meta-annotation類型,分別是:Target、Retention、Documented、Inherited,它們被用來提供對其它annotation類型作說明。 這些類型和它們所支持的類在java.lang.annotation包中可以找到。
@Target的用法:指示注釋類型所適用的程序元素的種類。如果注釋類型聲明中不存在 Target 元注釋,則聲明的類型可以用在任一程序元素上。如果存在這樣的元注釋,則編譯器強(qiáng)制實施指定的使用限制。 例如,以下這個注釋只能用來聲明方法:
?
@Target(ElementType.METHOD)public @interface MyAnnotation {... }
java.lang.annotation.ElementType是一個枚舉類型,它具有以下定義:
@Retention的用法:指示注釋類型的注釋要保留多久。如果注釋類型聲明中不存在 Retention 注釋,則保留策略默認(rèn)為 RetentionPolicy.CLASS,例如:
java.lang.annotation.RetentionPolicy是一個枚舉類型,它具有以下定義:
@Documented的用法:指示某一類型的注釋將通過 javadoc 和類似的默認(rèn)工具進(jìn)行文檔化。應(yīng)使用此類型來注釋這些類型的聲明:其注釋會影響由其客戶端注釋的元素的使用。如果類型聲明是用 Documented 來注釋的,則其注釋將成為注釋元素的公共 API 的一部分。Documented是一個沒有成員的注釋。
@Inherited的用法:指示注釋類型自動被子類繼承。 Inherited也是一個沒有成員的注釋。
注意,如果使用@Inherited注釋類以外的任何事物都是無效的。還要注意,此元注釋僅對從超類繼承注釋有效;對已實現(xiàn)接口的注釋無效。
總結(jié)
以上是生活随笔為你收集整理的JDK5--Annotation学习:基础(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: concurrent: ThreadPo
- 下一篇: JDK5--Annotation学习:基