Java中的注解與注解處理器
元注解
元注解的作用是負(fù)責(zé)注解其他注解。 Java5.0定義了4個(gè)標(biāo)準(zhǔn)的meta-annotation(元注解)類(lèi)型,它們被用來(lái)提供對(duì)其它注解類(lèi)型進(jìn)行說(shuō)明。
@Target
注解的作用目標(biāo),可以在哪些地方使用該注解。
注解的屬性
屬性名稱(chēng) | 屬性類(lèi)型 | 屬性默認(rèn)值 | 屬性描述 |
value | ElementType[] | 注解的作用目標(biāo)元素類(lèi)型枚舉集合 |
ElementType枚舉的取值
- TYPE:類(lèi),接口、枚舉、注解
- FIELD:字段、枚舉的常量
- METHOD:方法
- PARAMETER:參數(shù)
- CONSTRUCTOR:構(gòu)造器
- LOCAL_VARIABLE:局部變量
- ANNOTATION_TYPE:注解
- PACKAGE:包
@Retention
注解的保留策略,注解何種情況下仍然存在。
注解的屬性
屬性名稱(chēng) | 屬性類(lèi)型 | 屬性默認(rèn)值 | 屬性描述 |
value | RetentionPolicy | 注解的保留策略 |
RetentionPolicy枚舉的取值
- SOURCE:源文件中存在,編譯后的Class文件不存在
- CLASS:源文件、Class文件中存在,運(yùn)行時(shí)不存在
- RUNTIME:源文件、Class文件、運(yùn)行時(shí)都存在,所以可以在運(yùn)行中通過(guò)反射獲取到注解信息
@Documented
將此注解包含在javadoc中 。它代表著此注解會(huì)被javadoc工具提取成文檔。
@Inherited
允許子類(lèi)繼承父類(lèi)中的注解。如果一個(gè)使用了@Inherited 修飾的注解被用于一個(gè)類(lèi),則這個(gè)注解也將被用于該類(lèi)的子類(lèi)。
內(nèi)置注解
@Override
指明被注解修飾的方法是覆寫(xiě)父類(lèi)中的方法。
如果某個(gè)方法使用了該注解,卻沒(méi)有覆寫(xiě)父類(lèi)中的方法,編譯器就會(huì)生成一個(gè)錯(cuò)誤。
在子類(lèi)中覆寫(xiě)父類(lèi)或接口的方法的過(guò)程中,@Overide其實(shí)并不是必須的。但是還是建議使用這個(gè)注解。如果加了@Overide注解,在你沒(méi)有正確覆寫(xiě)父類(lèi)方法的情況下,編譯器會(huì)有錯(cuò)誤提示信息。
覆寫(xiě)失敗的情況舉例
- 子類(lèi)方法的大小寫(xiě)寫(xiě)錯(cuò)了、或者參數(shù)錯(cuò)了、或者是子類(lèi)自己定義的方法;
- 修改了父類(lèi)的方法的名字,那么之前重寫(xiě)的子類(lèi)方法將不再屬于重寫(xiě)。
@Deprecated
指明被注解修飾的類(lèi)、方法、變量等不建議使用。
當(dāng)編譯器遇到了使用@Deprecated修飾的類(lèi)、方法、變量等時(shí)會(huì)提示相應(yīng)的警告信息。
@Suppresswarnings
關(guān)閉編譯器生成的警告信息??梢孕揎楊?lèi)、方法、變量等。
它可以達(dá)到抑制編譯器編譯時(shí)產(chǎn)生警告的目的,使用@SuppressWarnings注解,采用就近原則,比如一個(gè)方法出現(xiàn)警告,盡量使用@SuppressWarnings注解這個(gè)方法,而不是注解方法所在的類(lèi)。所屬范圍越小越好,因?yàn)榉秶罅耍焕诎l(fā)現(xiàn)該類(lèi)下其他方法的警告信息。
但是不太建議使用@SuppressWarnings注解,使用此注解,開(kāi)發(fā)人員看不到編譯時(shí)編譯器提示的相應(yīng)的警告,不能選擇更好、更新的類(lèi)、方法或者不能編寫(xiě)更規(guī)范的編碼。同時(shí)后期更新JDK、jar包等源碼時(shí),使用@SuppressWarnings注解的代碼可能受新的JDK、jar包代碼的支持,出現(xiàn)錯(cuò)誤,仍然需要修改。
注解處理器
注解處理器(Annotation Processor Tool)簡(jiǎn)稱(chēng)APT,它是用于注解處理的命令行程序,它可以找到源碼中對(duì)應(yīng)注解的對(duì)象并使用注解處理器對(duì)其進(jìn)行處理。
Java中有默認(rèn)的注解處理器,使用者也可以自定義注解處理器,注冊(cè)后使用注解處理器處理注解,最終達(dá)到注解本身起到的效果。
注解處理器的原理就是:在需要使用的元素上(類(lèi)、變量、方法、參數(shù)等)加上注解,然后在編譯時(shí)把使用了這個(gè)注解的元素都收集起來(lái),做統(tǒng)一的處理。不管是運(yùn)行時(shí)注解還是編譯時(shí)注解,都會(huì)通過(guò)處理器在編譯時(shí)進(jìn)行掃描和處理注解。
注解處理器將標(biāo)記了注解的類(lèi),變量等作為輸入內(nèi)容,經(jīng)過(guò)注解處理器處理,生成想要生成的java代碼。所以處理器可以理解為就是一個(gè)生成代碼的工具,只是是通過(guò)注解的規(guī)則生成。生成后的代碼,可以看作是同一般代碼,最終被編譯。
讀取注解
讀取注解的核心是java.lang.reflect.AnnotatedElement接口。該接口用于獲取類(lèi)、方法、字段等的注解信息。
實(shí)現(xiàn)了這個(gè)接口的實(shí)現(xiàn)類(lèi)的實(shí)例對(duì)象代表了在當(dāng)前JVM中的一個(gè)“被注解元素”。使用這個(gè)接口中聲明的方法可以讀?。ㄍㄟ^(guò)Java的反射機(jī)制)“被注解元素”的注解。
這個(gè)接口中的所有方法返回的注解都是不可變的、并且都是可序列化的。因此這個(gè)接口中所有方法返 回的數(shù)組可以被調(diào)用者修改,而不會(huì)影響其返回給其他調(diào)用者的數(shù)組。
接口的常用方法
- default boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)
判斷該元素是否存在指定類(lèi)型的注解,存在返回true,否則返回false。注意:此方法會(huì)忽略注解對(duì)應(yīng)的注解容器。
- <T extends Annotation> T getAnnotation(Class<T> annotationClass)
返回該元素上存在的指定類(lèi)型的注解,如果該類(lèi)型注解不存在,則返回null。
- Annotation[] getAnnotations()
返回該元素上存在的所有注解,若沒(méi)有注解,返回空數(shù)組。
- default <T extends Annotation> T[] getAnnotationsByType(Class\<T> annotationClass)
返回元素上存在的指定類(lèi)型的注解數(shù)組,沒(méi)有注解對(duì)應(yīng)類(lèi)型的注解時(shí),返回空數(shù)組。
該方法的調(diào)用者可以隨意修改返回的數(shù)組,而不會(huì)對(duì)其他調(diào)用者返回的數(shù)組產(chǎn)生任何影響。
該方法與getAnnotation的區(qū)別在于:getAnnotationsByType會(huì)檢測(cè)注解對(duì)應(yīng)的重復(fù)注解容器。若該元素為類(lèi),當(dāng)前類(lèi)上找不到注解,且該注解為可繼承的,則會(huì)去父類(lèi)上檢測(cè)對(duì)應(yīng)的注解。
- default <T extends Annotation> T getDeclaredAnnotation(Class\<T> annotationClass)
返回該元素上直接存在的指定類(lèi)型的注解,如果該類(lèi)型注解不存在,則返回null。
該方法與此接口中的其他方法有所不同,該方法會(huì)忽略繼承的注解。如果注解沒(méi)有直接存在于此元素上,而是存在于元素的父類(lèi)上,也會(huì)返回null。
- default <T extends Annotation> T[] getDeclaredAnnotationsByType(Class\<T> annotationClass)
返回元素上存在的指定類(lèi)型的注解數(shù)組,沒(méi)有注解對(duì)應(yīng)類(lèi)型的注解時(shí),返回空數(shù)組。該方法會(huì)忽略繼承的注解。
- Annotation[] getDeclaredAnnotations()
返回該元素上存在的所有注解,若沒(méi)有注解,返回空數(shù)組。該方法將忽略繼承的注解。
接口的部分實(shí)現(xiàn)類(lèi)
- AccessibleObject:可訪問(wèn)對(duì)象,如:方法、構(gòu)造器、屬性等
- Class:類(lèi)
- Constructor:構(gòu)造器
- Executable:可執(zhí)行的,如:構(gòu)造器、方法
- Field:屬性
- Method:方法
- Package:包
- Parameter:參數(shù)
接口的部分子接口
- AnnotatedArrayType :被注解的數(shù)組類(lèi)型
- AnnotatedParameterizedType :被注解的參數(shù)化類(lèi)型
- AnnotatedType :被注解的類(lèi)型
- AnnotatedTypeVariable :被注解的類(lèi)型變量
- AnnotatedWildcardType :被注解的通配類(lèi)型
- GenericDeclaration :通用聲明,用于表示聲明型元素,如:類(lèi)、方法、構(gòu)造器等
- TypeVariable<D> :類(lèi)型變量
到此這篇關(guān)于Java中的注解與注解處理器的文章就介紹到這了,更多相關(guān)Java注解處理器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java圖片與二進(jìn)制相互轉(zhuǎn)換實(shí)現(xiàn)示例講解
這篇文章主要介紹了Java圖片與二進(jìn)制相互轉(zhuǎn)換實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2023-03-03Spring MVC完全注解方式配置web項(xiàng)目
這篇文章主要為大家詳細(xì)介紹了Spring MVC完全注解方式配置web項(xiàng)目的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10實(shí)例講解Java中random.nextInt()與Math.random()的基礎(chǔ)用法
今天小編就為大家分享一篇關(guān)于實(shí)例講解Java中random.nextInt()與Math.random()的基礎(chǔ)用法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-02-02SpringBoot中5種動(dòng)態(tài)代理的實(shí)現(xiàn)方案
在SpringBoot應(yīng)用中,動(dòng)態(tài)代理被廣泛用于實(shí)現(xiàn)事務(wù)管理、緩存、安全控制、日志記錄等橫切關(guān)注點(diǎn),下面小編為大家介紹一下SpringBoot中5種動(dòng)態(tài)代理的實(shí)現(xiàn)方案吧2025-04-04Spring cloud config集成過(guò)程詳解
這篇文章主要介紹了spring cloud config集成過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12IntelliJ IDEA2020.1版本更新pom文件自動(dòng)導(dǎo)包的方法
這篇文章主要介紹了IntelliJ IDEA2020.1版本更新pom文件自動(dòng)導(dǎo)包的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06