Java Annotation详解
http://djjchobits.iteye.com/blog/569000
元數(shù)據(jù)的作用
如果要對于元數(shù)據(jù)的作用進(jìn)行分類,目前還沒有明確的定義,不過我們可以根據(jù)它所起的作用,大致可分為三類:
l ???????? 編寫文檔:通過代碼里標(biāo)識的元數(shù)據(jù)生成文檔。
l ???????? 代碼分析:通過代碼里標(biāo)識的元數(shù)據(jù)對代碼進(jìn)行分析。
l ???????? 編譯檢查:通過代碼里標(biāo)識的元數(shù)據(jù)讓編譯器能實(shí)現(xiàn)基本的編譯檢查。
?
基本內(nèi)置注釋
??? @Override 注釋能實(shí)現(xiàn)編譯時(shí)檢查,你可以為你的方法添加該注釋,以聲明該方法是用于覆蓋父類中的方法。如果該方法不是覆蓋父類的方法,將會(huì)在編譯時(shí)報(bào)錯(cuò)。例如我們?yōu)槟愁愔貙憈oString() 方法卻寫成了tostring() ,并且我們?yōu)樵摲椒ㄌ砑恿?#64;Override 注釋;
???? @Deprecated 的作用是對不應(yīng)該在使用的方法添加注釋,當(dāng)編程人員使用這些方法時(shí),將會(huì)在編譯時(shí)顯示提示信息,它與javadoc 里的 @deprecated 標(biāo)記有相同的功能,準(zhǔn)確的說,它還不如javadoc @deprecated ,因?yàn)樗恢С謪?shù),
注意:要了解詳細(xì)信息,請使用 -Xlint:deprecation 重新編譯。
??? @SuppressWarnings 與前兩個(gè)注釋有所不同,你需要添加一個(gè)參數(shù)才能正確使用,這些參數(shù)值都是已經(jīng)定義好了的,我們選擇性的使用就好了,參數(shù)如下:
?
deprecation?? 使用了過時(shí)的類或方法時(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)于以上所有情況的警告
?
注意:要了解詳細(xì)信息,請使用 -Xlint:unchecked 重新編譯。
?
定制注釋類型
??? 好的,讓我們創(chuàng)建一個(gè)自己的注釋類型(annotation type )吧。它類似于新創(chuàng)建一個(gè)接口類文件,但為了區(qū)分,我們需要將它聲明為@interface, 如下例:
public @interface NewAnnotation {
?
}
?
使用定制的注釋類型
??? 我們已經(jīng)成功地創(chuàng)建好一個(gè)注釋類型NewAnnotation ,現(xiàn)在讓我們來嘗試使用它吧,如果你還記得本文的第一部分,那你應(yīng)該知道他是一個(gè)標(biāo)記注釋,使用也很容易,如下例:
public class AnnotationTest {
?
??? @NewAnnotation
??? public static void main(String[] args) {
???
??? }
}
?
添加變量
??? J2SE 5.0 里,我們了解到內(nèi)置注釋@SuppressWarnings() 是可以使用參數(shù)的,那么自定義注釋能不能定義參數(shù)個(gè)數(shù)和類型呢?答案是當(dāng)然可以,但參數(shù)類型只允許為基本類型、String 、Class 、枚舉類型等,并且參數(shù)不能為空。我們來擴(kuò)展NewAnnotation ,為之添加一個(gè)String 類型的參數(shù),示例代碼如下:
public @interface NewAnnotation {
?
??? String value();
}
??? 使用該注釋的代碼如下:正如你所看到的,該注釋的使用有兩種寫法,這也是在之前的文章里所提到過的。如果你忘了這是怎么回事,那就再去翻翻吧。
public class AnnotationTest {
?
??? @NewAnnotation("Just a Test.")
??? public static void main(String[] args) {
??????? sayHello();
??? }
???
??? @NewAnnotation(value="Hello NUMEN.")
??? public static void sayHello() {
??????? // do something
??? }
}
?
為變量賦默認(rèn)值
??? 我們對Java 自定義注釋的了解正在不斷的增多,不過我們還需要更過,在該條目里我們將了解到如何為變量設(shè)置默認(rèn)值,我們再對NewAnnotaion 進(jìn)行修改,看看它會(huì)變成什么樣子,不僅參數(shù)多了幾個(gè),連類名也變了。但還是很容易理解的,我們先定義一個(gè)枚舉類型,然后將參數(shù)設(shè)置為該枚舉類型,并賦予默認(rèn)值。
public @interface Greeting {
?
??? public enum FontColor {RED, GREEN, BLUE};
?
??? String name();
?
??? String content();
???
??? FontColor fontColor() default FontColor.BLUE;
}
?
限定注釋使用范圍
??? 當(dāng)我們的自定義注釋不斷的增多也比較復(fù)雜時(shí),就會(huì)導(dǎo)致有些開發(fā)人員使用錯(cuò)誤,主要表現(xiàn)在不該使用該注釋的地方使用。為此,Java 提供了一個(gè)ElementType 枚舉類型來控制每個(gè)注釋的使用范圍,比如說某些注釋只能用于普通方法,而不能用于構(gòu)造函數(shù)等。下面是Java 定義的ElementType 枚舉:
package java.lang.annotation;
?
public enum ElementType {
? TYPE,???????? // Class, interface, or enum (but not annotation)
? FIELD,??????? // Field (including enumerated values)
??METHOD,?????? // Method (does not include constructors)
? PARAMETER,??????? // Method parameter
? CONSTRUCTOR,????? // Constructor
? LOCAL_VARIABLE,?? // Local variable or catch clause
? ANNOTATION_TYPE,? // Annotation Types (meta-annotations)
? PACKAGE?????? // Java package
}
??? 下面我們來修改Greeting 注釋,為之添加限定范圍的語句,這里我們稱它為目標(biāo)(Target )使用方法也很簡單,如下:
?
@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR })
public @interface Greeting {
}
正如上面代碼所展示的,我們只允許Greeting 注釋標(biāo)注在普通方法和構(gòu)造函數(shù)上,使用在包申明、類名等時(shí),會(huì)提示錯(cuò)誤信息。
?
注釋保持性策略
public enum RetentionPolicy {
? SOURCE,// Annotation is discarded by the compiler
? CLASS,// Annotation is stored in the class file, but ignored by the VM
? RUNTIME// Annotation is stored in the class file and read by the VM
}
??? RetentionPolicy 的使用方法與ElementType 類似,簡單代碼示例如下:
@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR })
?
文檔化功能
??? Java 提供的Documented 元注釋跟Javadoc 的作用是差不多的,其實(shí)它存在的好處是開發(fā)人員可以定制Javadoc 不支持的文檔屬性,并在開發(fā)中應(yīng)用。它的使用跟前兩個(gè)也是一樣的,簡單代碼示例如下:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR })
public @interface Greeting {
}
?
值得大家注意的是,如果你要使用@Documented 元注釋,你就得為該注釋設(shè)置RetentionPolicy.RUNTIME 保持性策略。為什么這樣做,應(yīng)該比較容易理解,這里就不提了。
?
標(biāo)注繼承
繼承應(yīng)該是Java 提供的最復(fù)雜的一個(gè)元注釋了,它的作用是控制注釋是否會(huì)影響到子類,簡單代碼示例如下:
@Inherited
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR })
public @interface Greeting {
}
?
讀取注釋信息
??? 當(dāng)我們想讀取某個(gè)注釋信息時(shí),我們是在運(yùn)行時(shí)通過反射來實(shí)現(xiàn)的,如果你對元注釋還有點(diǎn)印象,那你應(yīng)該記得我們需要將保持性策略設(shè)置為RUNTIME ,也就是說只有注釋標(biāo)記了@Retention(RetentionPolicy.RUNTIME) 的,我們才能通過反射來獲得相關(guān)信息,下面的例子我們將沿用前面幾篇文章中出現(xiàn)的代碼,并實(shí)現(xiàn)讀取AnnotationTest 類所有方法標(biāo)記的注釋并打印到控制臺。好了,我們來看看是如何實(shí)現(xiàn)的吧:
public class AnnotationIntro {
?
??? public static void main(String[] args) throws Exception {
?
??????? Method[] methods = Class.forName(
??????????????? "com.gelc.annotation.demo.customize.AnnotationTest")
??????????????? .getDeclaredMethods();
??????? Annotation[] annotations;
?
??????? for (Method method : methods) {
??????????? annotations = method.getAnnotations();
??????????? for (Annotation annotation : annotations) {
??????????????? System.out.println(method.getName() + " : "
??????????????????????? + annotation.annotationType().getName());
??????????? }
?
********************************************************************************
?
Annotation(注解)
Annotation對于程序運(yùn)行沒有影響,它的目的在于對編譯器或分析工具說明程序的某些信息,您可以
在包,類,方法,域成員等加上Annotation.每一個(gè)Annotation對應(yīng)于一個(gè)實(shí)際的Annotation類型.
1??限定Override父類方法@Override
??java.lang.Override是J2SE5.0中標(biāo)準(zhǔn)的Annotation類型之一,它對編譯器說明某個(gè)方法必須
??是重寫父類中的方法.編譯器得知這項(xiàng)信息后,在編譯程序時(shí)如果發(fā)現(xiàn)被@Override標(biāo)示的方法
??并非重寫父類中的方法,就會(huì)報(bào)告錯(cuò)誤.
??例,如果在定義新類時(shí)想要重寫Object類的toString()方法,可能會(huì)寫成這樣:
??public class CustomClass{
????public String ToString(){
??????return "customObject";
????}
??}
??在編寫toString()方法時(shí),因?yàn)檩斎脲e(cuò)誤或其他的疏忽,將之寫成ToString()了,編譯這個(gè)類時(shí)
??并不會(huì)出現(xiàn)任何的錯(cuò)誤,編譯器不會(huì)知道您是想重寫toString()方法,只會(huì)以為是定義了一個(gè)新
??的ToString()方法.
??可以使用java.lang.Override這個(gè)Annotation類型,在方法上加一個(gè)@Override的Annotation
??這可以告訴編譯器現(xiàn)在定義的這個(gè)方法,必須是重寫父類中的同包方法.
??public class CustomClass{
????@Override
????public String toString(){
??????return "coustomObject";
????}
??}
??java.lang.Override是一個(gè)Marker Annotation,簡單地說就是用于標(biāo)示的Annotation,Annotation
??名稱本身表示了要給工具程序的信息。
??
??Annotation類型與Annotation實(shí)際上是有區(qū)分的,Annotation是Annotation類型的實(shí)例,例如
??@Override是個(gè)Annotation,它是java.lang.Override類型的一個(gè)實(shí)例,一個(gè)文件中可以有很多
??個(gè)@Override,但它們都是屬于java.lang.Override類型。
??
2??標(biāo)示方法為Deprecated @Deprecated
??java.lang.Deprecated也是J2SE5.0中標(biāo)準(zhǔn)的Annotation類型之一。它對編譯器說明某個(gè)方法已經(jīng)不
??建議使用。如果有開發(fā)人員試圖使用或重寫被@Deprecated標(biāo)示的方法,編譯器必須提出警告信息。
??例:
??public class Something{
????@Deprecated
????public Something getSomething(){
??????return new Something();
????}
??}
??如果有人試圖在繼承這個(gè)類后重寫getSomething()方法,或是在程序中調(diào)用getSomething()方法,
??則編譯時(shí)會(huì)有警告出現(xiàn)。
??java.lang.Deprecated也是一個(gè)Marker Annotation簡單地說就是用于標(biāo)示。
??
3??抑制編譯器警告 @SuppressWarnings
??java.lang.SuppressWarnings也是J2SE5.0中標(biāo)準(zhǔn)的Annotation類型之一,它對編譯器說明某個(gè)方法
??中若有警告信息,則加以抑制,不用在編譯完成后出現(xiàn)警告。
??例:
??public class SomeClass2{
????@SuppressWarnings(value={"unchecked"});
????public void doSomething(){
??????Map map = new HashMap();
??????map.put("some","thing");
????}
??}
??這樣,編譯器將忽略unchecked的警告,您也可以指定忽略多個(gè)警告:
??@SuppressWarnings(value={"unchecked","deprecation"});
??@SuppressWarnings是所謂的Single-Value Annotation,因?yàn)檫@樣的Annotation只有一個(gè)成員,稱為
??value成員,可在使用Annotation時(shí)作額外的信息指定。
??
??
??
自定義Annotation類型
??可以自定義Annotation類型,并使用這些自定義的Annotation類型在程序代碼中使用Annotation,這些
??Annotation將提供信息給程序代碼分析工具。
??首先來看看如何定義Marker Annotation,也就是Annotation名稱本身即提供信息。對于程序分析工具來
??說,主要是檢查是否有Marker Annotation的出現(xiàn),并做出對應(yīng)的動(dòng)作。要定義一個(gè)Annotation所需的動(dòng)作
??,就類似于定義一個(gè)接口,只不過使用的是@interface。
??例:
??public @interface Debug{}
??
??由于是一個(gè)Marker Annotation,所以沒有任何成員在Annotation定義中。編譯完成后,就可以在程序代碼
??中使用這個(gè)Annotation。
??public class SomeObject{
????@Debug
????public void doSomething(){
?????......
????}
??}
??稍后可以看到如何在Java程序中取得Annotation信息(因?yàn)橐褂肑ava程序取得信息,所以還要設(shè)置
??meta-annotation,稍后會(huì)談到)
??
??接著來看看如何定義一個(gè)Single-Value Annotation,它只有一個(gè)Value成員。
??例:
??public @interface UnitTest{
????String value();
??}
??實(shí)際上定義了value()方法,編譯器在編譯時(shí)會(huì)自動(dòng)產(chǎn)生一個(gè)value的域成員,接著在使用UnitTest
??Annotation時(shí)要指定值。如:
??public class MathTool{
???@UnitTest("GCD")
???public static int gcdOf(int num1,int num2){
?????...............
???}
??}
??@UnitTest("GCD")實(shí)際上是@UnitTest(value="GCD")的簡便寫法,value也可以是數(shù)組值。如:
??public @interface FunctionTest{
????String[] value();
??}
??在使用時(shí),可以寫成@FunctionTest({"method1","method2"})這樣的簡便形式?;蚴?br /> ??@FunctionTest(value={"method1","method2"})這樣的詳細(xì)形式.
??
??也可以對value成員設(shè)置默認(rèn)值,使用default關(guān)鍵詞即可。
??例:
??public @interface UnitTest2{
????String value() default "noMethod";
??}
??這樣如果使用@UnitTest2時(shí)沒有指定value值,則value默認(rèn)就是noMethod.
??
??
??也可以為Annotation定義額外的成員,以提供額外的信息給分析工具,如:
??public @interface Process{
????public enum Current{NONE,REQUIRE,ANALYSIS,DESIGN,SYSTEM};
????Current current() default Current.NONE;
????String tester();
????boolean ok();
??}
??運(yùn)用:
??public class Application{
????@process(
??????current = Process.Current.ANALYSIS,
??????tester = "Justin Lin",
??????ok = true
????)
????public void doSomething(){
??????...........
????}
??}
??當(dāng)使用@interface自行定義Annotation類型時(shí),實(shí)際上是自動(dòng)繼承了
??java.lang.annotation接口,并由編譯器自動(dòng)完成其他產(chǎn)生的細(xì)節(jié),并且在定義Annotation類型時(shí),
??不能繼承其他的Annotation類型或接口.
??定義Annotation類型時(shí)也可以使用包機(jī)制來管理類。由于范例所設(shè)置的包都是onlyfun.caterpillar,
??所以可以直接使用Annotation類型名稱而不指定包名,但如果是在別的包下使用這些自定義的Annotation
??,記得使用import告訴編譯器類型的包們置。
??如:
??import onlyfun.caterpillar.Debug;
??public class Test{
????@Debug
????public void doTest(){
??????......
????}
??}
??或是使用完整的Annotation名稱.如:
??public class Test{
????@onlyfun.caterpillar.Debug
????public void doTest(){
??????......
????}
??}
??
??
??
meta-annotation
??所謂neta-annotation就是Annotation類型的數(shù)據(jù),也就是Annotation類型的Annotation。在定義
??Annotation類型時(shí),為Annotation類型加上Annotation并不奇怪,這可以為處理Annotation類型
??的分析工具提供更多的信息。
??
1??告知編譯器如何處理annotation @Retention
??java.lang.annotation.Retention類型可以在您定義Annotation類型時(shí),指示編譯器該如何對待自定
??義的Annotation類型,編譯器默認(rèn)會(huì)將Annotation信息留在.class文件中,但不被虛擬機(jī)讀取,而僅用
??于編譯器或工具程序運(yùn)行時(shí)提供信息。
??
??在使用Retention類型時(shí),需要提供java.lang.annotation.RetentionPolicy的枚舉類型。
??RetentionPolicy的定義如下所示:
??package java.lang.annotation;
??public enum RetentionPolicy{
????SOURCE,//編譯器處理完Annotation信息后就沒有事了
????CLASS,//編譯器將Annotation存儲于class文件中,默認(rèn)
????RUNTIME //編譯器將Annotation存儲于class文件中,可由VM讀入
??}
??
??RetentionPolicy為SOURCE的例子是@SuppressWarnings,這個(gè)信息的作用僅在編譯時(shí)期告知
??編譯器來抑制警告,所以不必將這個(gè)信息存儲在.class文件中。
??
??RetentionPolicy為RUNTIME的時(shí)機(jī),可以像是您使用Java設(shè)計(jì)一個(gè)程序代碼分析工具,您必須讓VM能讀出
??Annotation信息,以便在分析程序時(shí)使用,搭配反射機(jī)制,就可以達(dá)到這個(gè)目的。\
??
??J2SE6.0的java.lang.reflect.AnnotatedElement接口中定義有4個(gè)方法:
??public Annotation getAnnotation(Class annotationType)
??public Annotation[] getAnnotations();
??public Annotation[] getDeclaredAnnotations()
??public boolean isAnnotationPresent(Class annotationType);
??
??Class,Constructor,field,Method,Package等類,都實(shí)現(xiàn)了AnnotatedElement接口,所以可以從這些
??類的實(shí)例上,分別取得標(biāo)示于其上的Annotation與相關(guān)信息。由于在執(zhí)行時(shí)讀取Annotation信息,所以定
??義Annotation時(shí)必須設(shè)置RetentionPolicy為RUNTIME,也就是可以在VM中讀取Annotation信息。
??例:
??package onlyfun.caterpillar;
??import java.lang.annotation.Retention;
??import java.lang.annotation.RetentionPllicy;
??
??@Retention(RetentionPolicy.RUNTIME)
??public @interface SomeAnnotation{
????String value();
????String name();
??}
??由于RetentionPolicy為RUNTIME,編譯器在處理SomeAnnotation時(shí),會(huì)將Annotation及給定的相關(guān)信息
??編譯至.class文件中,并設(shè)置為VM可以讀出Annotation信息。接下來:
??package onlyfun.caterpillar;
??public class SomeClass3{
????@SomeAnotation{
??????value="annotation value1",
??????name="annotation name1"
????}
????public void doSomething(){
??????......
????}
??}
??
??
??現(xiàn)在假設(shè)要設(shè)計(jì)一個(gè)源代碼分析工具來分析所設(shè)計(jì)的類,一些分析時(shí)所需的信息已經(jīng)使用Annotation標(biāo)示于類
??中了,可以在執(zhí)行時(shí)讀取這些Annotation的相關(guān)信息。例:
??
??package onlyfun.caterpillar;
??
??import java.lang.annotation.Annotation;
??import java.lang.reflect.Method;
??
??public class AnalysisApp{
????public static void main(String [] args) throws NoSuchMethodException{
??????Class<SomeClass3> c = SomeClass3.class;
??????//因?yàn)镾omeAnnotation標(biāo)示于doSomething()方法上
??????//所以要取得doSomething()方法的Method實(shí)例
??????Method method = c.getMethod("doSomething");
??????//如果SomeAnnotation存在
??????if(method.isAnnotationPresent(SomeAnnotation.class){
????????System.out.println("找到@SomeAnnotation");
????????//取得SomeAnnotation
????????SomeAnnotation annotation = method.getAnnotation(SomeAnnotation.class);
????????//取得vlaue成員值
????????System.out.println(annotation.value);
????????//取得name成員值
????????System.out.println(annotation.name());
??????}else{
????????System.out.println("找不到@SomeAnnotation");
??????}
??????//取得doSomething()方法上所有的Annotation
??????Annotation[] annotations = method.getAnnotations();
??????//顯示Annotation名稱
??????for(Annotation annotation : annotations){
????????System.out.println("Annotation名稱:"+annotation.annotationType().getName());
??????}
????}
??}
??若Annotation標(biāo)示于方法上,就要取得方法的Method代表實(shí)例,同樣的,如果Annotation標(biāo)示于類或包上,
??就要分別取得類的Class代表的實(shí)例或是包的Package代表的實(shí)例。之后可以使用實(shí)例上的getAnnotation()
??等相關(guān)方法,以測試是否可取得Annotation或進(jìn)行其他操作。
??
2??限定annotation使用對象 @Target
??在定義Annotation類型時(shí),使用java.lang.annotation.Target可以定義其適用的時(shí)機(jī),在定義時(shí)要指定
??java.lang.annotation.ElementType的枚舉值之一。
??public enum elementType{
????TYPE,//適用class,interface,enum
????FIELD,//適用于field
????METHOD,//適用于method
????PARAMETER,//適用method上之parameter
????CONSTRUCTOR,//適用constructor
????LOCAL_VARIABLE,//適用于區(qū)域變量
????ANNOTATION_TYPE,//適用于annotation類型
????PACKAGE,//適用于package
??}
??
??舉例,假設(shè)定義Annotation類型時(shí),要限定它只能適用于構(gòu)造函數(shù)與方法成員,則:
??package onlyfun.caterpillar;
??
??import java.lang.annotation.Target;
??import java.lang.annotation.ElementType;
??
??@Target({ElementType.CONSTRUCTOR,ElementType.METHOD})
??public @interface MethodAnnotation{}
??
??將MethodAnnotation標(biāo)示于方法之上,如:
??
??public class SomeoneClass{
????@onlyfun.caterpillar.MethodAnnotation
????public void doSomething(){
??????......
????}
??}
??
3??要求為API文件的一部分 @Documented
?
??在制作Java Doc文件時(shí),并不會(huì)默認(rèn)將Annotation的數(shù)據(jù)加入到文件中.Annnotation用于標(biāo)示程序代碼以便
??分析工具使用相關(guān)信息,有時(shí)Annotation包括了重要的信息,您也許會(huì)想要在用戶制作Java Doc文件的同時(shí),
??也一并將Annotation的信息加入到API文件中。所以在定義Annotation類型時(shí),可以使用
??java.lang.annotation.Documented.例:
??
??package onlyfun.caterpillar;
??
??import java.lang.annotation.Documented;
??import java.lang.annotation.Retention;
??import java.lang.annotation.RetentionPolicy;
??
??@Documented
??@Retention(RetentionPolicy.RUNTIME)
??public @interface TwoAnnotation{}
??
??使用java.lang.annotation.Documented為定義的Annotation類型加上Annotation時(shí),必須同時(shí)使用Retention
??來指定編譯器將信息加入.class文件,并可以由VM讀取,也就是要設(shè)置RetentionPolicy為RUNTIME。接著可以使
??用這個(gè)Annotation,并產(chǎn)生Java Doc文件,這樣可以看到文件中包括了@TwoAnnotation的信息.
??
4??子類是否可以繼承父類的annotation @Inherited
??在定義Annotation類型并使用于程序代碼上后,默認(rèn)父類中的Annotation并不會(huì)被繼承到子類中。可以在定義
??Annotation類型時(shí)加上java.lang.annotation.Inherited類型的Annotation,這讓您定義的Annotation類型在
??被繼承后仍可以保留至子類中。
??例:
??package onlyfun.caterpillar;
??
??import java.lang.annotation.Retention;
??import java.lang.annotation.RetentionPolicy;
??import java.lang.annotation.Inherited;
??
??@Retention(RetentionPolicy.RUNTIME)
??@Inherited
??public @interface ThreeAnnotation{
????String value();
????String name();
??}
??可以在下面的程序中使用@ThreeAnnotation:
??public class SomeoneClass{
????@onlyfun.caterpillar.ThreeAnnotation(
??????value = "unit",
??????name = "debug1"
????)
????public void doSomething(){
??????.....
????}
??}
??如果有一個(gè)類繼承了SomeoneClass類,則@ThreeAnnotation也會(huì)被繼承下來。
?
總結(jié)
以上是生活随笔為你收集整理的Java Annotation详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux 使用 touch 修改文件的
- 下一篇: 同步锁ReentrantLock