java的annotation_Java Annotation认知(包括框架图、详细介绍、示例说明)
摘要
Java Annotation是JDK5.0引入的一種注釋機(jī)制。
網(wǎng)上很多關(guān)于Java Annotation的文章,看得人眼花繚亂。Java Annotation本來很簡單的,結(jié)果說的人沒說清楚;弄的看的人更加迷糊。
我按照自己的思路,對(duì)Annotation進(jìn)行了整理。理解 Annotation 的關(guān)鍵,是理解Annotation的語法和用法,對(duì)這些內(nèi)容,我都進(jìn)行了詳細(xì)說明;理解Annotation的語法和用法之后,再看Annotation的框架圖,可能有更深刻體會(huì)。廢話就說這么多,下面開始對(duì)Annotation進(jìn)行說明。若您發(fā)現(xiàn)文章中存在錯(cuò)誤或不足的地方,希望您能指出!
第1部分 Annotation架構(gòu)
先看看Annotation的架構(gòu)圖:
從中,我們可以看出:
(01) 1個(gè)Annotation 和 1個(gè)RetentionPolicy關(guān)聯(lián)。
可以理解為:每1個(gè)Annotation對(duì)象,都會(huì)有唯一的RetentionPolicy屬性。
(02) 1個(gè)Annotation 和 1~n個(gè)ElementType關(guān)聯(lián)。
可以理解為:對(duì)于每1個(gè)Annotation對(duì)象,可以有若干個(gè)ElementType屬性。
(03) Annotation 有許多實(shí)現(xiàn)類,包括:Deprecated, Documented, Inherited, Override等等。
Annotation 的每一個(gè)實(shí)現(xiàn)類,都“和1個(gè)RetentionPolicy關(guān)聯(lián)”并且“和1~n個(gè)ElementType關(guān)聯(lián)”。
下面,我先介紹框架圖的左半邊(如下圖),即Annotation, RetentionPolicy, ElementType;然后在就Annotation的實(shí)現(xiàn)類進(jìn)行舉例說明。
第2部分 Annotation組成部分
1 annotation組成成分
java annotation 的組成中,有3個(gè)非常重要的主干類。它們分別是:
(01) Annotation.java
packagejava.lang.annotation;public interfaceAnnotation {booleanequals(Object obj);inthashCode();
String toString();
Class extends Annotation>annotationType();
}
(02) ElementType.java
packagejava.lang.annotation;public enumElementType {
TYPE,/*類、接口(包括注釋類型)或枚舉聲明*/FIELD,/*字段聲明(包括枚舉常量)*/METHOD,/*方法聲明*/PARAMETER,/*參數(shù)聲明*/CONSTRUCTOR,/*構(gòu)造方法聲明*/LOCAL_VARIABLE,/*局部變量聲明*/ANNOTATION_TYPE,/*注釋類型聲明*/PACKAGE/*包聲明*/}
(03) RetentionPolicy.java
packagejava.lang.annotation;public enumRetentionPolicy {
SOURCE,/*Annotation信息僅存在于編譯器處理期間,編譯器處理完之后就沒有該Annotation信息了*/CLASS,/*編譯器將Annotation存儲(chǔ)于類對(duì)應(yīng)的.class文件中。默認(rèn)行為*/RUNTIME/*編譯器將Annotation存儲(chǔ)于class文件中,并且可由JVM讀入*/}
說明:
(01) Annotation 就是個(gè)接口。
“每1個(gè)Annotation” 都與 “1個(gè)RetentionPolicy”關(guān)聯(lián),并且與 “1~n個(gè)ElementType”關(guān)聯(lián)。可以通俗的理解為:每1個(gè)Annotation對(duì)象,都會(huì)有唯一的RetentionPolicy屬性;至于ElementType屬性,則有1~n個(gè)。
(02) ElementType 是Enum枚舉類型,它用來指定Annotation的類型。
“每1個(gè)Annotation” 都與 “1~n個(gè)ElementType”關(guān)聯(lián)。當(dāng)Annotation與某個(gè)ElementType關(guān)聯(lián)時(shí),就意味著:Annotation有了某種用途。
例如,若一個(gè)Annotation對(duì)象是METHOD類型,則該Annotation只能用來修飾方法。
(03) RetentionPolicy 是Enum枚舉類型,它用來指定Annotation的策略。通俗點(diǎn)說,就是不同RetentionPolicy類型的Annotation的作用域不同。
“每1個(gè)Annotation” 都與 “1個(gè)RetentionPolicy”關(guān)聯(lián)。
a) 若Annotation的類型為 SOURCE,則意味著:Annotation僅存在于編譯器處理期間,編譯器處理完之后,該Annotation就沒用了。
例如,“ @Override ”標(biāo)志就是一個(gè)Annotation。當(dāng)它修飾一個(gè)方法的時(shí)候,就意味著該方法覆蓋父類的方法;并且在編譯期間會(huì)進(jìn)行語法檢查!編譯器處理完后,“@Override”就沒有任何作用了。
b) 若Annotation的類型為 CLASS,則意味著:編譯器將Annotation存儲(chǔ)于類對(duì)應(yīng)的.class文件中,它是Annotation的默認(rèn)行為。
c) 若Annotation的類型為 RUNTIME,則意味著:編譯器將Annotation存儲(chǔ)于class文件中,并且可由JVM讀入。
這時(shí),只需要記住“每1個(gè)Annotation” 都與 “1個(gè)RetentionPolicy”關(guān)聯(lián),并且與 “1~n個(gè)ElementType”關(guān)聯(lián)。學(xué)完后面的內(nèi)容之后,再回頭看這些內(nèi)容,會(huì)更容易理解。
第3部分 java自帶的Annotation
理解了上面的3個(gè)類的作用之后,我們接下來可以講解Annotation實(shí)現(xiàn)類的語法定義了。
1 Annotation通用定義
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)public @interfaceMyAnnotation1 {
}
說明:
上面的作用是定義一個(gè)Annotation,它的名字是MyAnnotation1。定義了MyAnnotation1之后,我們可以在代碼中通過“@MyAnnotation1”來使用它。
其它的,@Documented, @Target, @Retention, @interface都是來修飾MyAnnotation1的。下面分別說說它們的含義:
(01) @interface
使用@interface定義注解時(shí),意味著它實(shí)現(xiàn)了java.lang.annotation.Annotation接口,即該注解就是一個(gè)Annotation。
定義Annotation時(shí),@interface是必須的。
注意:它和我們通常的implemented實(shí)現(xiàn)接口的方法不同。Annotation接口的實(shí)現(xiàn)細(xì)節(jié)都由編譯器完成。通過@interface定義注解后,該注解不能繼承其他的注解或接口。
(02) @Documented
類和方法的Annotation在缺省情況下是不出現(xiàn)在javadoc中的。如果使用@Documented修飾該Annotation,則表示它可以出現(xiàn)在javadoc中。
定義Annotation時(shí),@Documented可有可無;若沒有定義,則Annotation不會(huì)出現(xiàn)在javadoc中。
(03) @Target(ElementType.TYPE)
前面我們說過,ElementType 是Annotation的類型屬性。而@Target的作用,就是來指定Annotation的類型屬性。
@Target(ElementType.TYPE) 的意思就是指定該Annotation的類型是ElementType.TYPE。這就意味著,MyAnnotation1是來修飾“類、接口(包括注釋類型)或枚舉聲明”的注解。
定義Annotation時(shí),@Target可有可無。若有@Target,則該Annotation只能用于它所指定的地方;若沒有@Target,則該Annotation可以用于任何地方。
(04) @Retention(RetentionPolicy.RUNTIME)
前面我們說過,RetentionPolicy 是Annotation的策略屬性,而@Retention的作用,就是指定Annotation的策略屬性。
@Retention(RetentionPolicy.RUNTIME) 的意思就是指定該Annotation的策略是RetentionPolicy.RUNTIME。這就意味著,編譯器會(huì)將該Annotation信息保留在.class文件中,并且能被虛擬機(jī)讀取。
定義Annotation時(shí),@Retention可有可無。若沒有@Retention,則默認(rèn)是RetentionPolicy.CLASS。
2 java自帶的Annotation
通過上面的示例,我們能理解:@interface用來聲明Annotation,@Documented用來表示該Annotation是否會(huì)出現(xiàn)在javadoc中, @Target用來指定Annotation的類型,@Retention用來指定Annotation的策略。
理解這一點(diǎn)之后,我們就很容易理解java中自帶的Annotation的實(shí)現(xiàn)類,即Annotation架構(gòu)圖的右半邊。如下圖:
java 常用的Annotation:
@Deprecated -- @Deprecated 所標(biāo)注內(nèi)容,不再被建議使用。
@Override-- @Override 只能標(biāo)注方法,表示該方法覆蓋父類中的方法。
@Documented-- @Documented 所標(biāo)注內(nèi)容,可以出現(xiàn)在javadoc中。
@Inherited-- @Inherited只能被用來標(biāo)注“Annotation類型”,它所標(biāo)注的Annotation具有繼承性。
@Retention-- @Retention只能被用來標(biāo)注“Annotation類型”,而且它被用來指定Annotation的RetentionPolicy屬性。
@Target-- @Target只能被用來標(biāo)注“Annotation類型”,而且它被用來指定Annotation的ElementType屬性。
@SuppressWarnings-- @SuppressWarnings 所標(biāo)注內(nèi)容產(chǎn)生的警告,編譯器會(huì)對(duì)這些警告保持靜默。
由于“@Deprecated和@Override”類似,“@Documented, @Inherited, @Retention, @Target”類似;下面,我們只對(duì)@Deprecated, @Inherited, @SuppressWarnings 這3個(gè)Annotation進(jìn)行說明。
2.1 @Deprecated
@Deprecated 的定義如下:
@Documented
@Retention(RetentionPolicy.RUNTIME)public @interfaceDeprecated {
}
說明:
(01) @interface -- 它的用來修飾Deprecated,意味著Deprecated實(shí)現(xiàn)了java.lang.annotation.Annotation接口;即Deprecated就是一個(gè)注解。
(02) @Documented -- 它的作用是說明該注解能出現(xiàn)在javadoc中。
(03) @Retention(RetentionPolicy.RUNTIME) -- 它的作用是指定Deprecated的策略是RetentionPolicy.RUNTIME。這就意味著,編譯器會(huì)將Deprecated的信息保留在.class文件中,并且能被虛擬機(jī)讀取。
(04) @Deprecated 所標(biāo)注內(nèi)容,不再被建議使用。
例如,若某個(gè)方法被 @Deprecated 標(biāo)注,則該方法不再被建議使用。如果有開發(fā)人員試圖使用或重寫被@Deprecated標(biāo)示的方法,編譯器會(huì)給相應(yīng)的提示信息。示例如下:
源碼如下(DeprecatedTest.java):
1 packagecom.skywang.annotation;2
3 importjava.util.Date;4 importjava.util.Calendar;5
6 public classDeprecatedTest {7 //@Deprecated 修飾 getString1(),表示 它是建議不被使用的函數(shù)
8 @Deprecated9 private static voidgetString1(){10 System.out.println("Deprecated Method");11 }12
13 private static voidgetString2(){14 System.out.println("Normal Method");15 }16
17 //Date是日期/時(shí)間類。java已經(jīng)不建議使用該類了
18 private static voidtestDate() {19 Date date = new Date(113, 8, 25);20 System.out.println(date.getYear());21 }22 //Calendar是日期/時(shí)間類。java建議使用Calendar取代Date表示“日期/時(shí)間”
23 private static voidtestCalendar() {24 Calendar cal =Calendar.getInstance();25 System.out.println(cal.get(Calendar.YEAR));26 }27
28 public static voidmain(String[] args) {29 getString1();30 getString2();31 testDate();32 testCalendar();33 }34 }
View Code
說明:
上面是eclipse中的截圖,比較類中 “getString1() 和 getString2()” 以及 “testDate() 和 testCalendar()” 。
(01) getString1() 被@Deprecated標(biāo)注,意味著建議不再使用getString1();所以getString1()的定義和調(diào)用時(shí),都會(huì)一橫線。這一橫線是eclipse()對(duì)@Deprecated方法的處理。
getString2() 沒有被@Deprecated標(biāo)注,它的顯示正常。
(02) testDate() 調(diào)用了Date的相關(guān)方法,而java已經(jīng)建議不再使用Date操作日期/時(shí)間。因此,在調(diào)用Date的API時(shí),會(huì)產(chǎn)生警告信息,途中的warnings。
testCalendar() 調(diào)用了Calendar的API來操作日期/時(shí)間,java建議用Calendar取代Date。因此,操作Calendar不回產(chǎn)生warning。
2.2 @Inherited
@Inherited 的定義如下:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)public @interfaceInherited {
}
說明:
(01) @interface -- 它的用來修飾Inherited,意味著Inherited實(shí)現(xiàn)了java.lang.annotation.Annotation接口;即Inherited就是一個(gè)注解。
(02) @Documented -- 它的作用是說明該注解能出現(xiàn)在javadoc中。
(03) @Retention(RetentionPolicy.RUNTIME) -- 它的作用是指定Inherited的策略是RetentionPolicy.RUNTIME。這就意味著,編譯器會(huì)將Inherited的信息保留在.class文件中,并且能被虛擬機(jī)讀取。
(04) @Target(ElementType.ANNOTATION_TYPE) -- 它的作用是指定Inherited的類型是ANNOTATION_TYPE。這就意味著,@Inherited只能被用來標(biāo)注“Annotation類型”。
(05) @Inherited 的含義是,它所標(biāo)注的Annotation將具有繼承性。
假設(shè),我們定義了某個(gè)Annotaion,它的名稱是MyAnnotation,并且MyAnnotation被標(biāo)注為@Inherited。現(xiàn)在,某個(gè)類Base使用了MyAnnotation,則Base具有了“具有了注解MyAnnotation”;現(xiàn)在,Sub繼承了Base,由于MyAnnotation是@Inherited的(具有繼承性),所以,Sub也“具有了注解MyAnnotation”。
@Inherited的使用示例
源碼如下(InheritableSon.java):
1 /**
2 * @Inherited 演示示例3 *4 *@authorskywang5 * @email kuiwu-wang@163.com6 */
7 packagecom.skywang.annotation;8
9 importjava.lang.annotation.Target;10 importjava.lang.annotation.ElementType;11 importjava.lang.annotation.Retention;12 importjava.lang.annotation.RetentionPolicy;13 importjava.lang.annotation.Inherited;14
15 /**
16 * 自定義的Annotation。17 */
18 @Target(ElementType.TYPE)19 @Retention(RetentionPolicy.RUNTIME)20 @Inherited21 @interfaceInheritable22 {23 }24
25 @Inheritable26 classInheritableFather27 {28 publicInheritableFather() {29 //InheritableBase是否具有 Inheritable Annotation
30 System.out.println("InheritableFather:"+InheritableFather.class.isAnnotationPresent(Inheritable.class));31 }32 }33
34 /**
35 * InheritableSon 類只是繼承于 InheritableFather,36 */
37 public class InheritableSon extendsInheritableFather38 {39 publicInheritableSon() {40 super(); //調(diào)用父類的構(gòu)造函數(shù)41 //InheritableSon類是否具有 Inheritable Annotation
42 System.out.println("InheritableSon:"+InheritableSon.class.isAnnotationPresent(Inheritable.class));43 }44
45 public static voidmain(String[] args)46 {47 InheritableSon is = newInheritableSon();48 }49 }
運(yùn)行結(jié)果:
InheritableFather:true
InheritableSon:true
現(xiàn)在,我們對(duì)InheritableSon.java進(jìn)行修改:注釋掉“Inheritable的@Inherited注解”。
源碼如下(InheritableSon.java):
1 /**
2 * @Inherited 演示示例3 *4 *@authorskywang5 * @email kuiwu-wang@163.com6 */
7 packagecom.skywang.annotation;8
9 importjava.lang.annotation.Target;10 importjava.lang.annotation.ElementType;11 importjava.lang.annotation.Retention;12 importjava.lang.annotation.RetentionPolicy;13 importjava.lang.annotation.Inherited;14
15 /**
16 * 自定義的Annotation。17 */
18 @Target(ElementType.TYPE)19 @Retention(RetentionPolicy.RUNTIME)20 //@Inherited
21 @interfaceInheritable22 {23 }24
25 @Inheritable26 classInheritableFather27 {28 publicInheritableFather() {29 //InheritableBase是否具有 Inheritable Annotation
30 System.out.println("InheritableFather:"+InheritableFather.class.isAnnotationPresent(Inheritable.class));31 }32 }33
34 /**
35 * InheritableSon 類只是繼承于 InheritableFather,36 */
37 public class InheritableSon extendsInheritableFather38 {39 publicInheritableSon() {40 super(); //調(diào)用父類的構(gòu)造函數(shù)41 //InheritableSon類是否具有 Inheritable Annotation
42 System.out.println("InheritableSon:"+InheritableSon.class.isAnnotationPresent(Inheritable.class));43 }44
45 public static voidmain(String[] args)46 {47 InheritableSon is = newInheritableSon();48 }49 }
View Code
運(yùn)行結(jié)果:
InheritableFather:true
InheritableSon:false
對(duì)比上面的兩個(gè)結(jié)果,我們發(fā)現(xiàn):當(dāng)注解Inheritable被@Inherited標(biāo)注時(shí),它具有繼承性。否則,沒有繼承性。
2.3 @SuppressWarnings
@SuppressWarnings 的定義如下:
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)public @interfaceSuppressWarnings {
String[] value();
}
說明:
(01) @interface -- 它的用來修飾SuppressWarnings,意味著SuppressWarnings實(shí)現(xiàn)了java.lang.annotation.Annotation接口;即SuppressWarnings就是一個(gè)注解。
(02) @Retention(RetentionPolicy.SOURCE) -- 它的作用是指定SuppressWarnings的策略是RetentionPolicy.SOURCE。這就意味著,SuppressWarnings信息僅存在于編譯器處理期間,編譯器處理完之后SuppressWarnings就沒有作用了。
(03) @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) -- 它的作用是指定SuppressWarnings的類型同時(shí)包括TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE。
TYPE意味著,它能標(biāo)注“類、接口(包括注釋類型)或枚舉聲明”。
FIELD意味著,它能標(biāo)注“字段聲明”。
METHOD意味著,它能標(biāo)注“方法”。
PARAMETER意味著,它能標(biāo)注“參數(shù)”。
CONSTRUCTOR意味著,它能標(biāo)注“構(gòu)造方法”。
LOCAL_VARIABLE意味著,它能標(biāo)注“局部變量”。
(04) String[] value(); 意味著,SuppressWarnings能指定參數(shù)
(05) SuppressWarnings 的作用是,讓編譯器對(duì)“它所標(biāo)注的內(nèi)容”的某些警告保持靜默。例如,"@SuppressWarnings(value={"deprecation", "unchecked"})" 表示對(duì)“它所標(biāo)注的內(nèi)容”中的 “SuppressWarnings不再建議使用警告”和“未檢查的轉(zhuǎn)換時(shí)的警告”保持沉默。示例如下:
源碼如下(SuppressWarningTest.java):
1 packagecom.skywang.annotation;2
3 importjava.util.Date;4
5 public classSuppressWarningTest {6
7 //@SuppressWarnings(value={"deprecation"})
8 public static voiddoSomething(){9 Date date = new Date(113, 8, 26);10 System.out.println(date);11 }12
13 public static voidmain(String[] args) {14 doSomething();15 }16 }
View Code
說明:
(01) 左邊的圖中,沒有使用 @SuppressWarnings(value={"deprecation"}) , 而Date屬于java不再建議使用的類。因此,調(diào)用Date的API時(shí),會(huì)產(chǎn)生警告。
而右邊的途中,使用了 @SuppressWarnings(value={"deprecation"})。因此,編譯器對(duì)“調(diào)用Date的API產(chǎn)生的警告”保持沉默。
補(bǔ)充:SuppressWarnings 常用的關(guān)鍵字的表格
deprecation --使用了不贊成使用的類或方法時(shí)的警告
unchecked--執(zhí)行了未檢查的轉(zhuǎn)換時(shí)的警告,例如當(dāng)使用集合時(shí)沒有用泛型 (Generics) 來指定集合保存的類型。
fallthrough--當(dāng) Switch 程序塊直接通往下一種情況而沒有 Break 時(shí)的警告。
path--在類路徑、源文件路徑等中有不存在的路徑時(shí)的警告。
serial--當(dāng)在可序列化的類上缺少 serialVersionUID 定義時(shí)的警告。finally -- 任何 finally子句不能正常完成時(shí)的警告。
all-- 關(guān)于以上所有情況的警告。
第4部分 Annotation 的作用
Annotation 是一個(gè)輔助類,它在Junit、Struts、Spring等工具框架中被廣泛使用。
我們在編程中經(jīng)常會(huì)使用到的Annotation作用有:
1 編譯檢查
Annotation具有“讓編譯器進(jìn)行編譯檢查的作用”。
例如,@SuppressWarnings, @Deprecated和@Override都具有編譯檢查作用。
(01) 關(guān)于@SuppressWarnings和@Deprecated,已經(jīng)在“第3部分”中詳細(xì)介紹過了。這里就不再舉例說明了。
(02) 若某個(gè)方法被 @Override的 標(biāo)注,則意味著該方法會(huì)覆蓋父類中的同名方法。如果有方法被@Override標(biāo)示,但父類中卻沒有“被@Override標(biāo)注”的同名方法,則編譯器會(huì)報(bào)錯(cuò)。示例如下:
源碼(OverrideTest.java):
1 packagecom.skywang.annotation;2
3 /**
4 * @Override測試程序5 *6 *@authorskywang7 * @email kuiwu-wang@163.com8 */
9 public classOverrideTest {10
11 /**
12 * toString() 在java.lang.Object中定義;13 * 因此,這里用 @Override 標(biāo)注是對(duì)的。14 */
15 @Override16 publicString toString(){17 return "Override toString";18 }19
20 /**
21 * getString() 沒有在OverrideTest的任何父類中定義;22 * 但是,這里卻用 @Override 標(biāo)注,因此會(huì)產(chǎn)生編譯錯(cuò)誤!23 */
24 @Override25 publicString getString(){26 return "get toString";27 }28
29 public static voidmain(String[] args) {30 }31 }
View Code
上面是該程序在eclipse中的截圖。從中,我們可以發(fā)現(xiàn)“getString()”函數(shù)會(huì)報(bào)錯(cuò)。這是因?yàn)椤癵etString() 被@Override所標(biāo)注,但在OverrideTest的任何父類中都沒有定義getString1()函數(shù)”。
“將getString() 上面的@Override注釋掉”,即可解決該錯(cuò)誤。
2 在反射中使用Annotation
在反射的Class, Method, Field等函數(shù)中,有許多于Annotation相關(guān)的接口。
這也意味著,我們可以在反射中解析并使用Annotation。
源碼如下(AnnotationTest.java):
packagecom.skywang.annotation;importjava.lang.annotation.Annotation;importjava.lang.annotation.Target;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Inherited;importjava.lang.reflect.Method;/*** Annotation在反射函數(shù)中的使用示例
*
*@authorskywang
* @email kuiwu-wang@163.com*/@Retention(RetentionPolicy.RUNTIME)
@interfaceMyAnnotation {
String[] value()default "unknown";
}/*** Person類。它會(huì)使用MyAnnotation注解。*/
classPerson {/*** empty()方法同時(shí)被 "@Deprecated" 和 “@MyAnnotation(value={"a","b"})”所標(biāo)注
* (01) @Deprecated,意味著empty()方法,不再被建議使用
* (02) @MyAnnotation, 意味著empty() 方法對(duì)應(yīng)的MyAnnotation的value值是默認(rèn)值"unknown"*/@MyAnnotation
@Deprecatedpublic voidempty(){
System.out.println("\nempty");
}/*** sombody() 被 @MyAnnotation(value={"girl","boy"}) 所標(biāo)注,
* @MyAnnotation(value={"girl","boy"}), 意味著MyAnnotation的value值是{"girl","boy"}*/@MyAnnotation(value={"girl","boy"})public void somebody(String name, intage){
System.out.println("\nsomebody: "+name+", "+age);
}
}public classAnnotationTest {public static void main(String[] args) throwsException {//新建Person
Person person = newPerson();//獲取Person的Class實(shí)例
Class c = Person.class;//獲取 somebody() 方法的Method實(shí)例
Method mSomebody = c.getMethod("somebody", new Class[]{String.class, int.class});//執(zhí)行該方法
mSomebody.invoke(person, new Object[]{"lily", 18});
iteratorAnnotations(mSomebody);//獲取 somebody() 方法的Method實(shí)例
Method mEmpty = c.getMethod("empty", newClass[]{});//執(zhí)行該方法
mEmpty.invoke(person, newObject[]{});
iteratorAnnotations(mEmpty);
}public static voiditeratorAnnotations(Method method) {//判斷 somebody() 方法是否包含MyAnnotation注解
if(method.isAnnotationPresent(MyAnnotation.class)){//獲取該方法的MyAnnotation注解實(shí)例
MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);//獲取 myAnnotation的值,并打印出來
String[] values =myAnnotation.value();for(String str:values)
System.out.printf(str+", ");
System.out.println();
}//獲取方法上的所有注解,并打印出來
Annotation[] annotations =method.getAnnotations();for(Annotation annotation : annotations){
System.out.println(annotation);
}
}
}
運(yùn)行結(jié)果:
somebody: lily, 18
girl, boy,
@com.skywang.annotation.MyAnnotation(value=[girl, boy])
empty
unknown,
@com.skywang.annotation.MyAnnotation(value=[unknown])
@java.lang.Deprecated()
3 根據(jù)Annotation生成幫助文檔
通過給Annotation注解加上@Documented標(biāo)簽,能使該Annotation標(biāo)簽出現(xiàn)在javadoc中。
4 能夠幫忙查看查看代碼
通過@Override, @Deprecated等,我們能很方便的了解程序的大致結(jié)構(gòu)。
另外,我們也可以通過自定義Annotation來實(shí)現(xiàn)一些功能。
點(diǎn)擊查看:
與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的java的annotation_Java Annotation认知(包括框架图、详细介绍、示例说明)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java socket 一边关闭_jav
- 下一篇: java封装弊端_JAVA-初步认识-第