免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
第三節(jié) 自定義Annotation
第三節(jié) 自定義Annotation
使用過spring框架,ejb框架,cxf,junit2等支持Annotation技術(shù)的框架的人都會很清楚,其中除了jdk自帶的一些Annotation以外,我們還可以自己定義很多Annotation幫助我們進行框架的搭建,這一小節(jié)我們將逐步的進行自定義Annotation的說明。
Ok,開始我們的第一個Annotation程序之旅吧。
一:Quick Start
定義Annotation的時候和定義接口的方式很類似,只不過再interface前面加了@,我感覺在這一點sun公司確實有一些吝嗇,為何不開辟一個新的類型標識符呢,呵呵,當(dāng)然這樣的抱怨也是無關(guān)緊要的,只要能達到目的即可。牢騷也不不多發(fā)了,直接上codes。
Java代碼  
  1. package com.wangwenjun.annatation.userdefined;  
  2.   
  3. public @interface UserdefinedAnnotation {  
  4.       
  5. }  
代碼很簡單,沒有任何的結(jié)構(gòu),只是一個空的Annotation,接下來演示一下如何對其進行使用。
Java代碼  
  1. package com.wangwenjun.annatation.userdefined;  
  2.   
  3. public class UseAnnotation {  
  4.       
  5.     @UserdefinedAnnotation  
  6.     public static void main(String[] args) {  
  7.         System.out.println("hello");  
  8.     }  
  9. }  
上述的代碼簡單到再也不能簡單,甚至簡單到說明不了任何問題,只是從它上面可以看得出來我們?nèi)绾巫远ㄒ粋€Annotation,并且如何的使用它,我們并沒有給自定義Annotation中添加任何的屬性,甚至沒有指定其保持力(Retention),可繼承性(Inherited),標注對象(Target)等,再接下來的描述中我們會逐步進行說明。
二:Annotation屬性值
Annotation屬性值大致有以下三種:
● 基本類型
● 數(shù)組類型
● 枚舉類型
我們在下面的文字中將會一個個的進行演示和說明。
1:基本串類型
Java代碼  
  1. package com.wangwenjun.annatation.userdefined;  
  2.   
  3. public @interface UserdefinedAnnotation {  
  4.     int value();  
  5.     String name();  
  6.     String address();  
  7. }  
上面是一個自定義的annotation,可能稍微有一些復(fù)雜,只不過是為了更多的說明一下問題,可以看出來在定義屬性的時候有點像interface定義方法一樣,每一個屬性名稱之后需要加上括號,接下來看看如何使用。
Java代碼  
  1. package com.wangwenjun.annatation.userdefined;  
  2. public class UseAnnotation {  
  3.       
  4. @UserdefinedAnnotation(value=123,name="wangwenjun",address="火星")  
  5.     public static void main(String[] args) {  
  6.         System.out.println("hello");  
  7.     }  
  8. }  
如果在使用UserdefinedAnnotation時候不給相關(guān)的屬性賦值,會出現(xiàn)錯誤。
需要說明的一點事如果一個annotation中只有一個屬性名字叫value,我沒在使用的時候可以給出屬性名也可以省略。
Java代碼  
  1. public @interface UserdefinedAnnotation {  
  2.     int value();  
  3. }  
  4. package com.wangwenjun.annatation.userdefined;  
  5.   
  6. public class UseAnnotation {  
  7.       
  8.     @UserdefinedAnnotation(value=123)  
  9.     public static void main(String[] args) {  
  10.         System.out.println("hello");  
  11.     }  
  12. }  
也可以寫成如下的形式
Java代碼  
  1. @UserdefinedAnnotation(123)  
  2.     public static void main(String[] args) {  
  3.         System.out.println("hello");  
  4. }  
直接對其進行了省略。如果定義的屬性名字不叫value,那么屬性名字是不可以省略的哦!那是因為value屬性名是annotation默認的一個屬性名,這一點很重要的哦,千萬不能忽略。
2:數(shù)組類型
我們在自定義annotation中定義一個數(shù)組類型的屬性,代碼如下:
Java代碼  
  1. public @interface UserdefinedAnnotation {  
  2.     int[] value();  
  3. }  
我們?nèi)绾问褂媚兀a如下:
Java代碼  
  1. public class UseAnnotation {  
  2.       
  3.     @UserdefinedAnnotation({123})  
  4.     public static void main(String[] args) {  
  5.         System.out.println("hello");  
  6.     }  
  7. }  
注意1:其中123外面的大括號是可以被省略的,因為只有一個元素,如果里面有一個以上的元素的話,花括號是不能被省略的哦。比如{123,234}。
注意2:其中屬性名value我們在使用的時候進行了省略,那是因為他叫value,如果是其他名字我們就不可以進行省略了必須是@UserdefinedAnnotation(屬性名={123,234})這樣的格式。
3:枚舉類型
自從jdk5.0以后,java引進了枚舉類型,我個人比較喜歡這樣的方式尤其在進行業(yè)務(wù)邏輯判斷的if或者switch子句中使用很方便,而且還不容易出錯,大多時候都是作為一個函數(shù)的形式參數(shù)而存在,關(guān)于枚舉類型的使用請查看相應(yīng)的doc文檔。
我們定義一個enum類型
Java代碼  
  1. package com.wangwenjun.annatation.userdefined;  
  2.   
  3. public enum DateEnum {  
  4.     Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday  
  5. }  
  6. 然后在定義一個annotation  
  7. package com.wangwenjun.annatation.userdefined;  
  8.   
  9. public @interface UserdefinedAnnotation {  
  10.     DateEnum week();  
  11. }  
可以看出annotation中的屬性類型為enum類型的,接下來我們看看他如何來使用
Java代碼  
  1. package com.wangwenjun.annatation.userdefined;  
  2.   
  3. public class UseAnnotation {  
  4.       
  5.     @UserdefinedAnnotation(week=DateEnum.Sunday)  
  6.     public static void main(String[] args) {  
  7.         System.out.println("hello");  
  8.     }  
  9. }  
在使用上也是很方便的,直接用來進行相關(guān)的引用,這樣再應(yīng)用的過程中就不會出現(xiàn)錯誤。
4:默認值
有時候我們在使用annotation的時候某一些屬性值是會被經(jīng)常使用到的,或者說他會有一個默認值給我們直接進行使用,那么我們在定義annotation的時候就可以為屬性直接給出默認值,下面進行一下簡單的示例。
Java代碼  
  1. public @interface UserdefinedAnnotation {  
  2.     String name() default "zhangsan";  
  3. }  
在使用的時候我們可以不進行指定
Java代碼  
  1. public class UseAnnotation {  
  2.       
  3.     @UserdefinedAnnotation()  
  4.     public static void main(String[] args) {  
  5.         System.out.println("hello");  
  6.     }  
  7. }  

當(dāng)然我們也可以自己對其進行重新的設(shè)置,其中數(shù)組和枚舉類型的默認值基本上類似,就不多做贅述了,自己進行測試即可。
5:注意
● Annotation是不可以繼承其他接口的,這一點是需要進行注意,這也是annotation的一個規(guī)定吧。
● Annotation也是存在包結(jié)構(gòu)的,在使用的時候直接進行導(dǎo)入即可。
● Annotation類型的類型只支持原聲數(shù)據(jù)類型,枚舉類型和Class類型的一維數(shù)組,其他的類型或者用戶自定義的類都是不可以作為annotation的類型,我查看過文檔并且進行過測試。
三:Retention標記
Retention標記是告知編譯器如何來處理我們自定義的annotation,指示注釋類型的注釋要保留多久。如果注釋類型聲明中不存在 Retention 注釋,則保留策略默認為 RetentionPolicy.CLASS。
查看他的源代碼,會發(fā)現(xiàn)他有一個屬性value,類型為RetentionPolicy,RetentionPolicy是一個枚舉類型。其中有三個類型的值分別代表不同的意思。
CLASS 編譯器將把注釋記錄在類文件中,但在運行時 VM 不需要保留注釋。

RUNTIME 編譯器將把注釋記錄在類文件中,在運行時 VM 將保留注釋,因此可以反射性地讀取。
SOURCE 編譯器要丟棄的注釋

下面是一段簡短的定義代碼示例。
Java代碼  
  1. package com.wangwenjun.annatation.userdefined;  
  2.   
  3. import java.lang.annotation.Retention;  
  4. import java.lang.annotation.RetentionPolicy;  
  5.   
  6. @Retention(RetentionPolicy.RUNTIME)  
  7. public @interface UserdefinedAnnotation {  
  8.     String name() default "zhangsan";  
  9. }  
從上面的實例中我們自定義的annotation是一個runntime范圍的annotation,也就是說他會保持在源文件中并且也會在運行時由JVM自動調(diào)用。
我們先對它有一個感性的認識,知道有這么一個東西,在后面的文章中我會以一個示例對其進行詳細的說明(會涉及到反射的相關(guān)東西)。其實Retention的名字翻譯過來就是“保持力”的意思,說明的很清楚,就是我的annotation存放在哪些地方,也就是說我的annotation他的影響力到底在哪。
四:AnnotatedElement
在jdk5.0以后java反射包增加了這樣一個接口,主要是用來對annotation進行操作的,其中AccessibleObject, Class, Constructor, Field, Method, Package都對其進行了實現(xiàn)繼承??偣灿幸韵滤膫€方法:
<T extends Annotation>
T
getAnnotation(Class<T> annotationType)
          如果存在該元素的指定類型的注釋,則返回這些注釋,否則返回 null。
Annotation[]
getAnnotations()
          返回此元素上存在的所有注釋。
Annotation[]
getDeclaredAnnotations()
          返回直接存在于此元素上的所有注釋。
boolean isAnnotationPresent(Class<? extends Annotation> annotationType)
          如果指定類型的注釋存在于此元素上,則返回 true,否則返回 false。
在接下來的章節(jié)中我們會進行說明。
五:Target 標記
在我們之前的實例中我們定義的annotation可以放在一個類的任何位置,那么我們是否可以對annotation的位置進行設(shè)置呢,答案是可以的,這就是我們所要說的的Target 標記,他里面也有一個枚舉類型的屬性value,其中枚舉類型為ElementType,有很多自定義的屬性,如下所示:

ANNOTATION_TYPE
          注釋類型聲明
CONSTRUCTOR
          構(gòu)造方法聲明
FIELD
          字段聲明(包括枚舉常量)
LOCAL_VARIABLE
          局部變量聲明
METHOD
          方法聲明
PACKAGE
          包聲明
PARAMETER
          參數(shù)聲明
TYPE
          類、接口(包括注釋類型)或枚舉聲明
上面的列表已經(jīng)講述的很清楚了,我們就不再進行說明了,直接來一個小程序進行演示吧,還是先來一個annotation,假設(shè)我們的annotation只能放在方法的前面
Java代碼  
  1. package com.wangwenjun.annatation.userdefined;  
  2.   
  3. import java.lang.annotation.ElementType;  
  4. import java.lang.annotation.Target;  
  5.   
  6. @Target(ElementType.METHOD)  
  7. public @interface UserdefinedAnnotation {  
  8.     String name() default "zhangsan";  
  9. }  
  10. package com.wangwenjun.annatation.userdefined;  
  11. public class UseAnnotation {  
  12.       
  13.     @UserdefinedAnnotation()  
  14.     public static void main(String[] args) {  
  15.         System.out.println("hello");  
  16.     }  
  17. }  
我們的annotation只能放在main方法上面放在其他的位置會出現(xiàn)錯誤。
六:Documented 標記
這個annotation非常簡單,也非常容易理解,使用過javadoc命令的人都會很清楚,我們可以用javadoc命令將方法,類,變量等前面的注釋轉(zhuǎn)換成文檔,在默認的情況下javadoc命令不會將我們的annotation生成再doc中去的,所以使用該標記就是告訴jdk讓它也將annotation生成到doc中去,比如:
Java代碼  
  1. package com.wangwenjun.annatation.userdefined;  
  2.   
  3. import java.lang.annotation.Documented;  
  4. import java.lang.annotation.ElementType;  
  5. import java.lang.annotation.Target;  
  6.   
  7. @Target(ElementType.METHOD)  
  8. @Documented  
  9. public @interface UserdefinedAnnotation {  
  10.     String name() default "zhangsan";  
  11. }  
七:Inherited標記
該標記的意思就是說,比如有一個類A,在他上面有一個標記annotation,那么A的子類B是否不用再次標記annotation就可以繼承得到呢?答案是肯定的,我們做一個簡單的演示,首先我們有一個annotation
Java代碼  
  1. package com.wangwenjun.annatation.userdefined;  
  2.   
  3. import java.lang.annotation.Documented;  
  4. import java.lang.annotation.ElementType;  
  5. import java.lang.annotation.Inherited;  
  6. import java.lang.annotation.Retention;  
  7. import java.lang.annotation.RetentionPolicy;  
  8. import java.lang.annotation.Target;  
  9.   
  10. @Documented  
  11. @Target(ElementType.TYPE)  
  12. @Retention(RetentionPolicy.RUNTIME)  
  13. @Inherited  
  14. public @interface UserdefinedAnnotation {  
  15.     String name() default "zhangsan";  
  16. }  
接著定義一個父類
package com.wangwenjun.annatation.userdefined;

@UserdefinedAnnotation
public class ParentClass {

}
父類什么都沒有干,只是一個空的類,并且有UserdefinedAnnotation的標記,然后我們寫一個繼承他的子類。
Java代碼  
  1. package com.wangwenjun.annatation.userdefined;  
  2.   
  3. public class ChildClass extends ParentClass{  
  4.       
  5. }  
我們準備工作都已經(jīng)做完了,現(xiàn)在就是利用反射機制進行一下簡短的測試
Java代碼  
  1. package com.wangwenjun.annatation.userdefined;  
  2.   
  3. public class TestInherited {  
  4.     public static void main(String[] args) {  
  5.         Class<ChildClass> clazz = ChildClass.class;  
  6.         boolean isExist=clazz.isAnnotationPresent(UserdefinedAnnotation.class);  
  7.         if(isExist){  
  8.             System.out.println("子類繼承了父類的annotation");  
  9.         }else{  
  10.             System.out.println("子類沒有繼承父類的annotation");  
  11.         }  
  12.     }  
  13. }  
打印結(jié)果為:子類繼承了父類的annotation??梢钥吹阶宇惞焕^承了父類的annotation標記。 
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Spring4新特性
應(yīng)用 JAXB 把 XML 轉(zhuǎn)換成相應(yīng)的 JavaBean
@interface java注解
java annotation(注解)
基礎(chǔ)篇:帶你從頭到尾玩轉(zhuǎn)注解
張龍 Annotation學(xué)習(xí)筆記
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服