當前位置:
首頁 > 知識 > 全面解析Java註解

全面解析Java註解

1. 了解註解

我們有必要對JDK 5.0新增的註解(Annotation)技術進行簡單的學習,因為Spring 支持@AspectJ,而@AspectJ本身就是基於JDK 5.0的註解技術。所以學習JDK 5.0的註解知識有助於我們更好地理解和掌握Spring的AOP技術。

對於Java開發人員來說,在編寫代碼時,除了源程序以外,我們還會使用 Javadoc標籤對類、方法或成員變數進行注釋,以便使用Javadoc工具生成和源代碼配套的Javadoc文檔。這些@param、@return 等Javadoc標籤就是註解標籤,它們為第三方工具提供了描述程序代碼的注釋信息。使用過Xdoclet的朋友,對此將更有感觸,像Struts、 Hibernate都提供了Xdoclet標籤,使用它們可以快速地生成對應程序代碼的配置文件。

JDK5.0註解可以看成是Javadoc標籤和Xdoclet標籤的延伸和發展。在JDK5.0中,我們可以自定義這些標籤,並通過Java語言的反射機制中獲取類中標註的註解,完成特定的功能。

註解是代碼的附屬信息,它遵循一個基本原則:註解不能直接干擾程序代碼的運行,無論增加或刪除註解,代碼都能夠正常運行。Java語言解釋器會忽略這些註解,而由第三方工具負責對註解進行處理。第三方工具可以利用代碼中的註解間接控制程序代碼的運行,它們通過Java反射機制讀取註解的信息,並根據這些信息更改目標程序的邏輯,而這正是Spring AOP對@AspectJ提供支持所採取的方法。

註解的語法比較簡單,除了@符號的使用以外,它基本上與java的固有語法一致,java內置了三種註解,定義在java.lang包中。

@Override:只能用在方法之上的,用來告訴別人這一個方法是改寫父類的。

@Deprecated:建議別人不要使用舊的API的時候用的,編譯的時候會用產生警告信息,可以設定在程序里的所有的元素上。

@SuppressWarnings:表示關閉一些不當的編譯器警告信息。

2. 定義註解

下面是一個定義註解的實例。

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Inherited

public @interface Description {

String value();

}

一個註解可以擁有多個成員,成員聲明和介面方法聲明類似,這裡,我們僅定義了一個成員,成員的聲明有以下幾點限制:

a) 成員以無入參無拋出異常的方式聲明,如boolean value(String str)、boolean value() throws Exception等方式是非法的;

b) 可以通過default為成員指定一個默認值,如String level() default "LOW_LEVEL"、int high() default 2是合法的,當然也可以不指定默認值;

c) 成員類型是受限的,合法的類型包括原始類型及其封裝類、String、Class、enums、註解類型,以及上述類型的數組類型。如ForumService value()、List foo()是非法的。

d) 如果註解只有一個成員,則成員名必須取名為value(),在使用時可以忽略成員名和賦值號(=),如@Description("使用註解的實例")。註解類擁有多個成員時,如果僅對value成員進行賦值則也可不使用賦值號,如果同時對多個成員進行賦值,則必須使用賦值號,如@DeclareParents (value = "NaiveWaiter", defaultImpl = SmartSeller.class)。

e) 註解類可以沒有成員,沒有成員的註解稱為標識註解,解釋程序以標識註解存在與否進行相應的處理;

註解定義包含四個元註解,分別為@Target,@Retention,@Documented,@Inherited。各元註解的作用如下:

1) @Target

表示該註解用於什麼地方,可能的 ElemenetType 參數包括:

? ElemenetType.CONSTRUCTOR 構造器聲明。

? ElemenetType.FIELD 域聲明(包括 enum 實例)。

? ElemenetType.LOCAL_VARIABLE 局部變數聲明。

? ElemenetType.METHOD 方法聲明。

? ElemenetType.PACKAGE 包聲明。

? ElemenetType.PARAMETER 參數聲明。

? ElemenetType.TYPE 類,介面(包括註解類型)或enum聲明。

2) @Retention

表示在什麼級別保存該註解信息。可選的 RetentionPolicy 參數包括:

? RetentionPolicy.SOURCE 註解將被編譯器丟棄。

? RetentionPolicy.CLASS 註解在class文件中可用,但會被VM丟棄。

? RetentionPolicy.RUNTIME VM將在運行期也保留注釋,因此可以通過反射機制讀取註解的信息。

舉一個例子,如@Override裡面的Retention設為SOURCE,編譯成功了就不要這一些檢查的信息,相反,@Deprecated裡面的Retention設為RUNTIME,表示除了在編譯時會警告我們使用了哪個被 Deprecated的方法,在執行的時候也可以查出該方法是否被Deprecated。

3) @Documented

將此註解包含在 javadoc 中

4) @Inherited

允許子類繼承父類中的註解

3. 使用註解

下面是一個使用註解註解的實例。

@Description(value="使用註解的實例")

public class TestAnnotation {

}

使用註解的語法:@(=,=,...)

如果成員是數組類型,可以通過{}進行賦值,如boolean數組的成員可以設置為。下面是幾個註解標註的例子:

1) 多成員的註解

@AnnoExample(id= {}, synopsis = "Enable time-travel", engineer = "Mr. Peabody")

2) 一個成員的註解,成員名為value

可以省略成員名和賦值符號:@Copyright("Right Reserved")

@Copyright("2011 bookegou.com All Right Reserved")

3) 無成員的註解

@Override

4) 成員為字元串數組的註解

@SuppressWarnings(value={"unchecked","fallthrough"})

5) 成員為註解數組類型的註解

@Reviews({@Review(grade=Review.Grade.EXCELLENT,reviewer="df"),

@Review(grade=Review.Grade.UNSATISFACTORY,reviewer="eg",

comment="This method needs an @Override annotation")})

@Reviews({@Review(grade=Review.Grade.EXCELLENT,reviewer="df"),

@Review(grade=Review.Grade.UNSATISFACTORY,reviewer="eg",

comment="This method needs an @Override annotation")})

@Reviews註解擁有一個@Review註解數組類型的成員,@Review註解類型有三個成員,其中reviewer、comment都是String類型,但comment有默認值,grade是枚舉類型的成員。

4. 解析註解

下面是一個解析註解的實例。

public class ParseAnnotation {

public static void main(String[] args) throws Exception{

final Class cls = Class.forName("com.annotation.TestAnnotation");

final Method[] method = cls.getMethods();

// 判斷是否有指定註解類型的註解

if(cls.isAnnotationPresent(Description.class)) {

// 根據註解類型返回指定類型的註解

Description des = (Description)cls.getAnnotation(Description.class);

}

}

}

輸出結果如下:

註解描述:使用註解的實例

前面提到過,註解不會直接影響程序的運行,但是第三方程序或工具可以利用代碼中的註解完成特殊的任務,間接控制程序的運行。對於RetentionPolicy.RUNTIME保留期限的註解,我們可以通過反射機制訪問類中的註解。

在JDK5.0里,Package、Class、Constructor、 Method以及Field等反射對象都新增了訪問註解信息的方法:T getAnnotation(Class annotationClass),該方法支持通過泛型直接返回註解對象。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 java吧 的精彩文章:

Java語言零基礎菜鳥入門 Java程序學習的要點
Java常用的7大排序演算法匯總
JAVA 初學問題
淺談代碼的 定位
2017年最值得學習的編程語言TOP,10

TAG:java吧 |

您可能感興趣

hbase查詢解析
Google兩步驗證全解析
解析|intel i7 CPU生產全過程圖解
Ansible 深度解析
Oracle集群軟體全解析
Json解析(jquery頁面)
Google 經典面試題解析
使用 Python 解析參數
藉助Jackson的JsonTypeInfo註解實現多態類的解析
realme X 產品圖曝光 真機全面解析
Google的開源Consent解決方案解析APUS研究院
Android Studio項目模板全面解析
Siemens MPI協議解析
Word2v的ec 原理解析!
mcu神器解析!
自定義fastjson解析+熱部署
my.cnf的中文解析
SparseArray 稀疏數組解析
AtomicInteger 源碼解析
Android項目解耦-路由框架ARouter源碼解析