您好,登錄后才能下訂單哦!
本篇內容主要講解“如何理解Java注解編程”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“如何理解Java注解編程”吧!
注解是什么
實現格式
從代碼來看我們知道注解的實現格式是:
public @interface MyAnnotation{ 屬性列表; }
所以我們有了第一直覺,注解可能是一個接口。通過查詢資料得知(可以通過反編譯軟件),實際上 @interface 是自定義接口對 annotation 接口的繼承,@interface 實際是一個語法糖。
import java.lang.annotation.Annotation; public interface MyAnnotation extends Annotation{ 屬性列表; }
使用位置
類、方法、成員變量、形參位置。
分類
不同角度,我們對注解能有不同的分類,但知道了注解的實現原理后就會明白,實際上用法和實現方法都是一回事。
來源
1. JDK注解:一般都是在編譯時起用作的注解,比如我們最為熟悉的 @Override。
2. 第三方框架注解
3. 自定義注解
運行機制(保留策略)
@Retention({保留策略}) public @interface MyAnnotation{ 屬性列表; }
1.源碼(SOURCE)注解:注解只在源碼中存在,編譯成.class文件就不存在了,也就是說只能起到 “看” 的作用。
2.編譯(CLASS)注解:注解在源碼和.class文件中都存在(JDK自帶注解都屬于編譯時注解),一般用來作語法校驗。
3.運行(RUNTIME)注解:在運行階段還起作用,甚至會影響運行邏輯的注解(@Autowired屬于運行時注解),第三方框架和自定注解一般采用 runtime 的保留策略,能實現依賴注入、切面編程等功能。
元注解
實際在上面,我們已經看到一個元注解了(@Retention)。元注解就是加在注解上描述注解的注解。 一共有5個。
1. @Documented
在生成javadoc的時候就會把@Documented注解給顯示出來。
2. @Target(關鍵)
限定作用位置,Method、Class等等。
9. @Inherited
被 @Inherited 注解的注解修飾了一個父類,如果他的子類沒有被其他注解修飾,則它的子類也繼承了父類的注解。
10. @Retention(關鍵)
上文的保留策略注解,影響注解作用。
6. @Repeatable (不重要)
@Repeatable 注解是用于聲明其它類型注解的元注解,來表示這個聲明的注解是可重復的。@Repeatable的值是另一個注解,其可以通過這個另一個注解的值來包含這個可重復的注解。
如何使用
我們先來了解一下注解粗淺的使用。最簡單的,
使用自定義注解就是分為三步:定義注解、使用注解、讀取注解。
摘自:https://www.zhihu.com/question/47449512/answer/658228092
我們只要牢牢地把握住這三步,就能掌握注解的使用。
定義注解
因為,注解的基本作用是根據注解中的值,判斷該如何執行被注解代碼塊。所以,在定義注解時,除了要根據功能加元注解外,還要根據業務意義,編寫合適的方法名稱。
比如,如果我們要編寫一個鎖注解:
@Documented @Retention(RUNTIME) @Target({TYPE, METHOD}) public @interface Lock { //輸鎖名稱 String lockName(); //被鎖值 String key(); //鎖級別 int level(); //異常 String exception() default ""; }
在一個注解中,能夠返回的類型有:基本數據類型、String、enum、Class、其他注解以及前幾者的一維數組。
注意: 如果沒有 default,那么使用時就必須要入參。
使用注解
注解在該注解的地方,入參必入參的參數。
Tips:如果注解中只有一個函數,雖然使用時候不需要加函數名稱就可以直接入參,但個人建議對于自定義注解,在入參時,還是將函數名稱寫全,增強代碼可讀性。
讀取注解
我們先想一想,如果是我們自己實現一個注解讀取的方法,我們該怎么來實現呢?
目前我想到的無非就是兩個:
1. 在字符串或字節碼文件中找注解:這個判斷可不好寫啊,而且復雜字符串處理不了。
2. 通過反射獲得類、方法、成員變量上的注解。
明眼人就能看出來 2 比 1 靠譜多了,而且還容易實現。
最簡單的一種讀取方式:
public static void main(String[] args) throws NoSuchMethodException { Class<Module> modelClazz = Module.class; Method method = modelClazz.getMethod("lock", null); Lock annotationLock = method.getAnnotation(Lock.class); //獲取注解在 lock 方法上的 value String lockName = annotationLock.lockName(); }
這也是框架注解的基本實現原理,因為要獲取注解的具體代碼塊,所以一般需要掃描包。
對于切面編程,引入依賴 aspectj 后,那我們就有了更簡單的調用方法:
//切面代碼節選 public Object around(ProceedingJoinPoint pjp) throws Throwable { MethodSignature signature = (MethodSignature) pjp.getSignature(); Lock lock = signature.getMethod().getAnnotation(Lock.class); lock.lockName(); }
具體關于切面編程與 joinpoint 的知識,可以參考:
https://blog.csdn.net/qq_15037231/article/details/80624064
注解的作用
至此我們可以總結出注解的作用。
* 編程提示
保留策略為源碼的注解,一般為提示性注解,比如 @deprecated。
* 用于切面,減少重復代碼
保留策略為運行的注解,0入侵改變函數的運行效果,一般用于重復性功能,比如日志輸出、數據格式校驗等。
* 簡化配置信息,項目結構
主要是對于 springboot 這個框架的作用。因為注解可以取值,所以在設置默認配置信息的同時,也支持輸入配置信息。
* 格式校驗
一般為代碼的語法檢驗,存在與 jdk 的注解包中,比如 @Override。
到此,相信大家對“如何理解Java注解編程”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。