Java四種元註解相關介紹
概述
註解從Java1.5
引入以來,不斷地簡化我們編寫程式碼的流程,逐漸的也成為了我們必學的一項技術。我們學習了各種註解,學習了他們的用法,學習了他們的限制,是否想過他們的組成呢,下面我將我對元註解的理解分享給大家。
元註解是用來修飾註解的註解,在java.lang.annotation
包下,當我們需要自己定義一個註解去做某些事情的時候,我們要對該註解進行一些限制,確保我們註解的作用域,有的註解有屬性,有的註解沒有屬性,我們點進去就能看到。這樣的註解一共有四個,如下圖
定義一個註解用@interface
來修飾檔案型別,這四個元註解我們一個一個分析
@Documented
該註解是用來宣告,我們的註解是否能被Javadoc
等API
文件生成工具展示出來,如果某個註解上面宣告瞭@Documented
,就說明這個註解可以被那些生成文件的工具展示出來。
我們點進去可以看到,該註解用到了三個註解,其中有他自己,還有兩個元註解,並且這個註解沒有屬性,所以我們的使用方法很簡單,就是寫或者不寫該註解。
@Retention
我們點進這個註解可以看到,首先他寫了@Documented
,說明他是可以被文件生成工具顯示到文件中,並且他有一條屬性,他同樣也對自己使用了@Retention
,並且給了一個值->RetentionPolicy.RUNTIME
,可以看到跟我們上邊的@Documented
註解是一樣的,然後我們點到RetentionPolicy
這個類中去看看這個位置都可以給什麼值
首先我們注意到了,這個類是個列舉類,也就是說我們還可以這樣寫
那麼這三個常量都代表什麼意思呢
- SOURCE:我們翻譯一下注釋:編譯器將丟棄註解就是說如果用了他,那麼你的註解編譯成
.class
檔案之後就會被丟掉,所以如果我們的註解是用來輔助編譯過程的,那麼我們可以用它。
例如
@SuppressWarnings
,我們通常用該註解來告訴編譯器忽略某些警告資訊,編譯之後我們就不需要了,所以這個場景用SOURCE肯定是沒毛病的
- CLASS:我們翻譯一下注釋:編譯器將註解記錄在類檔案中,
VM
在執行時不需要保留這些註釋。這是預設設定行為。也就是說,編譯器編譯成.class
檔案後,這個註解仍然存在,但是在我們的jvm
去載入.class
檔案的時候會被丟掉,這個使用的不多所以我們知道這個是什麼意思就行。如果不寫,預設就是選擇CLASS
。 - RUNTIME:使用率最高的一個常量,隨便去某個類庫裡去查一下註解,點進去基本都是RUNTIME。老樣子,我們先翻譯註釋:註釋將由編譯器記錄在類檔案中,並在執行時由
VM
定義,因此可以反射性地讀取。也就是說這個常量所定義的範圍是最大的了,都可以被反射了,也就是不光編譯器編譯了、JVM
載入了還能反射性的讀取到,會一直存在。我們自己在定義註解的時候,除非有特殊需要,一般業務也是用這個常量,比較方便一些。
@Target
由圖可以看到,這個元註解用到了三個元註解,有我們上邊說的兩個和他自己。此處我們不過多贅述。再看他的屬性,可以看到用到了中括號,說明註解的引數這裡是可以放一個列舉陣列的,我們點開列舉後可以看到宣告瞭很多常量。
老樣子先翻譯一下注釋,基本都能看出來是啥意思了,TYPE_PARAMETER
和TYPE_USE
是JDK1.8
加進來的
- TYPE:類、介面(包括註解型別)或列舉宣告。
- FIELD:欄位宣告(包括列舉常量)
- METHOD:方法宣告
- PARAMETER:形式引數宣告
- CONSTRUCTOR:建構函式宣告
- LOCAL_VARIABLE:區域性變數宣告
- ANNOTATION_TYPE:註釋型別宣告
- PACKAGE:包宣告
- TYPE_PARAMETER:型別引數宣告。該常量可以用於各種引數型別(包括類)的前面
- TYPE_USE:型別的使用。該常量可以用來標註任何型別的名稱,包括
TYPE_PARAMETER
的
所以我們可以根據我們的需要選擇此處的常量,當然可以多選
例如這樣,按照圖片的寫法,這個@annotationT
就既可以宣告在欄位上,又可以宣告在方法上。
@Inherited
如圖可見,這個註解是一個可以被文件生成工具顯示,不會被編譯器、JVM
丟棄,且用到了ANNOTATION_TYPE
,也就是說這個註解只能定義到註解上,所以他一定是用來規定註解的某些特性的。
老樣子我們翻譯一下上邊的註釋,由於篇幅較長此處不展示具體內容,大佬們可以點進去看看,大概是:被這個註解註釋的註解可以自動繼承的,查詢類上的註解型別,如果類宣告沒有針對該型別的註解將自動查詢超類(直到Object)
PS:請注意,如果註解型別用於註解類以外的任何內容,則此元註解型別無效。還要注意,此元註解只會導致註解從超類繼承;已實現介面上的註解沒有影響。
簡單說,如果想讓你定義的註解被繼承,那就把@Inherited
掛在你的註解上
總結
以上就是作用於我們所有註解上的元註解的基本資訊,我們明白每個元註解代表什麼意思會方便我們去理解一些JDK
自帶的、或者第三方類庫中定義或使用的註解,也會方便我們自己去定義一些註解,比如可以用註解的方式實現在操作我們自定義的註解註釋的方法執行之前或者之後要做些什麼,當我們真正會使用這些元註解去自定義屬於自己的註解的時候,一定會理解為什麼註解使用的如此普遍。
感謝各位大佬的閱讀ORZ,如果能幫到你是我的幸運,如果本篇部落格有任何問題歡迎留言指出,謝謝~