Java基礎(chǔ)元注解基本原理示例詳解
元注解
是負(fù)責(zé)對其它注解進(jìn)行說明的注解,自定義注解時(shí)可以使用元注解。Java 5 定義了 4 個(gè)注解,分別是 @Documented
、@Target
、@Retention
和 @Inherited
。Java 8 又增加了 @Repeatable
和 @Native
兩個(gè)注解。這些注解都可以在 java.lang.annotation
包中找到。下面主要介紹每個(gè)元注解的作用及使用。
@Documented
@Documented 是一個(gè)標(biāo)記注解,沒有成員變量。用 @Documented 注解修飾的注解類會被 JavaDoc 工具提取成文檔。默認(rèn)情況下,JavaDoc 是不包括注解的,但如果聲明注解時(shí)指定了 @Documented,就會被 JavaDoc 之類的工具處理,所以注解類型信息就會被包括在生成的幫助文檔中。
IDEA Documented 文檔生成
Tools -> Generate JavaDoc
@Target
@Target 注解用來指定一個(gè)注解的使用范圍,即被 @Target 修飾的注解可以用在什么地方。@Target 注解有一個(gè)成員變量(value)用來設(shè)置適用目標(biāo),value 是 java.lang.annotation.ElementType 枚舉類型的數(shù)組,下表為 ElementType 常用的枚舉常量。
類型 | 適用目標(biāo) |
---|---|
TYPE | 用于類、接口(包括注解類型)或 enum 聲明 |
FIELD | 用于成員變量(包括枚舉常量) |
METHOD | 用于方法 |
PARAMETER | 用于方法參數(shù) |
CONSTRUCTOR | 用于構(gòu)造器 |
LOCAL_VARIABLE | 用于局部變量 |
ANNOTATION_TYPE | 用于注解 |
PACKAGE | 用于包 |
TYPE_PARAMETER | 用來類型參數(shù)(JDK 1.8新增) |
TYPE_USE | 能標(biāo)注任何類型名稱(JDK 1.8新增) |
@Retention
@Retention 描述注解的生命周期,也就是該注解被保留的時(shí)間長短。@Retention 注解中的成員變量(value)用來設(shè)置保留策略,value 是 java.lang.annotation.RetentionPolicy
枚舉類型。
RetentionPolicy 有 3 個(gè)枚舉常量,如下所示:
- SOURCE:在源文件中有效(即源文件保留);
- CLASS:在 class 文件中有效(即 class 保留);
- RUNTIME:在運(yùn)行時(shí)有效(即運(yùn)行時(shí)保留);
生命周期大小排序?yàn)?SOURCE < CLASS < RUNTIME
,前者能使用的地方后者一定也能使用。
如果需要在運(yùn)行時(shí)去動態(tài)獲取注解信息,那只能用 RUNTIME 注解,如 @Documented 注解;如果要在編譯時(shí)進(jìn)行一些預(yù)處理操作,比如生成一些輔助代碼,就用 CLASS 注解,如 @NonNull 注解;如果只是做一些檢查性的操作,則可選用 SOURCE 注解,如 @Override 和 @SuppressWarnings 注解。
@Inherited
@Inherited 是一個(gè)標(biāo)記注解,用來指定該注解可以被繼承。使用 @Inherited 注解的 Class 類,表示這個(gè)注解可以被用于該 Class 類的子類。就是說如果某個(gè)類使用了被 @Inherited 修飾的注解,則其子類將自動具有該注解。
示例
創(chuàng)建一個(gè)自定義注解,代碼如下所示:
@Target({ ElementType.TYPE }) @Inherited @Retention(RetentionPolicy.RUNTIME) public @interface MyInherited { }
測試類代碼如下:
@MyInherited public class TestA { public static void main(String[] args) { System.out.println(TestA.class.getAnnotation(MyInherited.class)); System.out.println(TestB.class.getAnnotation(MyInherited.class)); System.out.println(TestC.class.getAnnotation(MyInherited.class)); } } class TestB extends TestA { } class TestC extends TestB { }
運(yùn)行結(jié)果為:
@MyInherited()
@MyInherited()
@MyInherited()
@Repeatable
@Repeatable 是 Java 8 新增,它允許在相同的程序元素中重復(fù)注解,在需要對同一種注解多次使用時(shí),往往需要借助該注解。Java 8 版本以前,同一個(gè)程序元素前最多只能有一個(gè)相同類型的注解,如果需要在同一個(gè)元素前使用多個(gè)相同類型的注解,則必須使用注解“容器”。
示例
Java 8 之前的相同類型的注解做法:
public @interface Roles { Role[] roles(); } public @interface Role { String roleName(); } public class RoleTest { @Roles(roles = {@Role(roleName = "roleA"), @Role(roleName = "roleB")}) public String doString(){ return "MingYue Repeatable 測試"; } }
Java 8 之后增加了重復(fù)注解,使用方式如下:
public @interface Roles { Role[] value(); } @Repeatable(Roles.class) public @interface Role { String roleName(); } public class RoleTest { @Role(roleName = "roleA") @Role(roleName = "roleB") public String doString(){ return "MingYue Repeatable 測試"; } }
兩者不同的地方是,創(chuàng)建重復(fù)注解 Role 時(shí)加上了 @Repeatable 注解,指向存儲注解 Roles,這樣在使用時(shí)就可以直接重復(fù)使用 Role 注解。
@Native
@Native 注解修飾成員變量,則表示這個(gè)變量可以被本地代碼引用,常常被代碼生成工具使用。
以上就是Java基礎(chǔ)元注解基本原理示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Java 元注解的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Spring security自定義用戶認(rèn)證流程詳解
這篇文章主要介紹了Spring security自定義用戶認(rèn)證流程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03如何在java 8 stream表達(dá)式實(shí)現(xiàn)if/else邏輯
這篇文章主要介紹了如何在java 8 stream表達(dá)式實(shí)現(xiàn)if/else邏輯,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04解決mybatis plus報(bào)錯(cuò)com.microsoft.sqlserver.jdbc.SQLServerE
這篇文章主要介紹了解決mybatis plus報(bào)錯(cuò)com.microsoft.sqlserver.jdbc.SQLServerException:必須執(zhí)行該語句才能獲得結(jié)果,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05玩轉(zhuǎn)SpringBoot2快速整合攔截器的方法
這篇文章主要介紹了玩轉(zhuǎn)SpringBoot2快速整合攔截器的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09SpringBoot啟動時(shí)自動執(zhí)行sql腳本的方法步驟
本文主要介紹了SpringBoot啟動時(shí)自動執(zhí)行sql腳本的方法步驟,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09java實(shí)現(xiàn)隊(duì)列queue數(shù)據(jù)結(jié)構(gòu)詳解
大家好,本篇文章主要講的是java實(shí)現(xiàn)隊(duì)列queue數(shù)據(jù)結(jié)構(gòu)詳解,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下2022-02-02Netty網(wǎng)絡(luò)編程零基礎(chǔ)入門
Netty是一個(gè)異步的、基于事件驅(qū)動的網(wǎng)絡(luò)應(yīng)用框架,用于快速開發(fā)可維護(hù)、高性能的網(wǎng)絡(luò)服務(wù)器和客戶端,如果你還不了解它的使用,就趕快繼續(xù)往下看吧2022-08-08Java引用傳遞和值傳遞棧內(nèi)存與堆內(nèi)存的指向操作
這篇文章主要介紹了Java引用傳遞和值傳遞棧內(nèi)存與堆內(nèi)存的指向操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09