第14 章 Annotation(註解)

14 Annotation(註解)

JDK 5 開始,java增加了對元數據(METAData)的支持,也就是Annotation(其實是代碼裏的特殊標記),這些標記可以在編譯、類加載、運行時被讀取,並執行相應的處理。通過註解程序員可以在不改變原有邏輯的情況下,在源文件中嵌入一些補充信息

Annotation 提供了一種爲程序元素設置的元數據的方法。指定指出的是,Annotation就像修飾符一樣 可以用來修飾 包 類 構造器 方法 成員變量 參數 局部變量

Annotation 是一個接口,程序可以通過反射來獲取指定程序元素的Annotation對象 然後通過Annotation對象來獲取註解裏的元數據。

 

14.1 基本Annotation

Annotation必須使用工具來處理,工具負責提取Annotation裏包含的元數據,工具還會根據這些元數據增加額外的功能,

使用Annotation時需要在前面增加@,並把該Annotation當成修飾符使用,用於修飾它支持的程序元素

5個基本的Annotation如下

1. @Override

2. @Deprecated

3. @Suppress Warnings

4. @Safa Varargs

5. @FunctionlInterface

 

14.1.1 限定重寫父類方法@Overrid

@Override就是用來指定方法覆蓋的,它可以強制一個子類必須覆蓋父類的方法(主要作用是用來保證子類的方法名不被寫錯,只能修飾方法)

 

14.1.2 標記已經過時 @Deprecated

@Deprecated用於表示某一個程序元素(類、方法)記過時,當程序使用已經過時的類、方法時將會給出警告

14.1.3 抑制編譯器警告@Suppress Warnings

@Suppress Warnings指示被該Annotation修飾的程序元素(以及該程序元素中所有子類元素)取消顯示執行的編譯器警告@Suppress Warnings會一直作用於該程序元素的所有子元素

14.1.4 java 7 的堆污染警告與@Safa Varargs

把一個不帶泛型的對象賦值給一個帶泛型的對象,往往會引發這種 堆污染

java 7 開始,java編譯器將會進行更嚴格的檢查,在定義方法時就發出堆污染警告,這樣保證更早的注意到漏洞

但有些時候也不需要看到這個警告 則可以通過如下三個方法啦抑制這些警告

1. 使用@Safa Varargs

2. 使用@Suppress Warnings“unchecked”)修飾

3. 編譯時使用-Xlint:varargs選項

 

14.1.5 java 8 的函數式接口與@FunctionlInterface

如果接口中只有一個抽象方法(可以包含多個默認方法或多個static方法),該接口就是函數式接口 @FunctionlInterface就是用來指定某一個接口必須是函數式接口

 

14.2 JDK的元Annotation

jdk處理在java.lang下提供了5個基本的Annotation之外,還在java.lang.annotion包下提供了6Meta Annotation (Annotation) 其中5個元Annotation用於修飾Annotation定義,其中@Repeatable 專門用於定義java 8 新增的重複註解

14.2.1 使用@Retention

@Retention只能用於修飾Annotation定義,用於指定被修飾的Annotation可以保留多長時間@Retention包含一個RetentionPolicy 類型的value 變量,所以使用@Retention時必須爲該value成員變量指定值

value成元變量有3個值

1. RetentionPolicy.CLASS 編譯器將Annotation記錄在class文件中,當運行java程序時,JVM不可以獲取Annotation信息(默認值)

2. RetentionPolicy.RUNTIME 編譯器將Annotation記錄在class文件中,當運行java程序時,JVM可以獲取Annotation信息,程序可以通過反射湖區該Annotation信息

3.RetentionPolicy.SOURCE Annotation只保存在源代碼中,編譯器直接丟棄這種Annotation

 

14.2.2 使用@Target

@Target也只能修飾一個Annotation定義,它用於指定被修飾的Annotation能用於修飾哪些程序單元@Target 也包含一個名爲value的成員變量

1. ElementType.ANNOTATION_TYPE 指定該策略的Annotation只能修飾Annotation

2. ElementType.CONSTRUCTOR指定該策略的Annotation只能修飾構造器

3. ElementType.FIELD 指定該策略只能修飾成員變量

4. ElementType.LOCAL_VARIABLE 指定該策略只能修飾局部變量

5. ElementType.METHOD 指定該策略只能修飾方法

6. ElementType.PACKAGE 指定該策略只能修飾包

7. ElementType.PARAMETER 指定該策略只能修飾參數

8. ElementType.TYPE 指定該策略只能修飾參數

 

14.2.3 使用@Documented

@Documented用於指定該元Annotation修飾的Annotation類被javadoc工具讀成文檔,表明白API中會包含Annotation的說明

 

14.2.4 使用@Inherited

@InheritedAnnotation指定被它修飾的Annotation將具有繼承性--如果一個類使用了@XXX註解 子類將自動繼承@XXX修飾

 

14.3 自定義Annotation

14.3.1 定義Annotation

定義新的Annotation類型使用@interface關鍵字,定義一個新的Annotation類型與定義一個接口非常像

 

定義了該Annotation之後,就可以在程序的任何地方使用該Annotation 使用Annotation的語法非常類似於 public final 這樣的修飾符

也可以定義Annotation的成員變量爲其制定初始值(默認值)制定成員變量的默認值可以使用default關鍵字 如果使用中指定了值則默認值就不會起作用

 

根據Annotation是否可以包含成員變量,可以把Annotation分爲兩類

1.標記 沒有定義成員變量的Annotation類型被稱爲標記

2.元數據 定義了成員變量的Annotation類型被稱爲 元數據

 

14.3.2 提前Annotation信息

使用了Annotation修飾類 方法成員變量等成員後,這些Annotation並不會自己生效,必須由開發者提供相應的工具來提取並處理Annotation信息

java使用Annotation接口來代表程序元素前面的註解,該接口是所有註解的父接口java 5 java.lang.reflect包下新增了AnnotationElement接口,該接口代碼程序中可以接收註解的程序元素

該接口下主要有如下幾個實現類 Class Construtor Field Method Package

 

java 1.5 java.lang.reflect包提供了反射API增加了讀取運行時Annotation的能力(只有定義Annotation時使用@Retention.RUNTIME時)該Annotation纔會在運行時可見,JVM纔會在加載*.class文件時讀取保存在class文件中 Annotation

AnnotationElement對象是所有元素的(Class Construtor Field Method Package )的父接口所有程序通過反射獲取了某個類的AnnotationElement對象,之後,程序就可以調用該對象的如下幾個方法來訪問Annotation元素

 

14.3.4 java 8 新增的重複註解

java 8 之前 同一個程序元素前最多隻能使用一個相同類型的Annotation;如果需要在同一個元素前使用多個相同類型的Annotation,則必須使用Annotation“容器”,有時需要在Action類中使用多個@Result註解

開發重複註解需要使用@Repeatable修飾

 

14.3.5 java 8 新增的 Type Annotation

java 8 ElementType枚舉增加了Tpye_PARAMETERTYPE_USE 兩個枚舉值,這樣就允許定義枚舉時,都是使用@TargetElement.TYPE_USE)這種註解被稱爲類型註解

 

java 8 開始可以在使用到類型的地方使用註解

1.創建對象(new關鍵字)

2.類型轉換

3.使用implement實現接口

4.使用throws什麼拋出異常

但是java 並沒有提供對Type Annotation執行檢查的框架,所有需要開發者自己實現Type Annotation的檢查框架

 

14.4 編譯時處理Annotation

APT(Annotation Processing Tool)是一種註解處理工具,它對源代碼進行檢測,並找出源代碼所包含的Annotation信息,然後針對Annotation信息進行額外的處理

使用APT 工具處理Annotation時,可以根據源文件中的Annotation生成額外的源文件和其他的文件,APT還會編譯生成的源代碼文件和原來的源文件,將他們一起生成class文件

 

API 可在編譯源文件是同時可以生成附屬文件 這些附屬文件也都和源代碼相關,使用APT可以代替傳統的對代碼信息和屬性文件的維護工作

 

每個Annotation處理器都需要實現javax.annotaton.processing 包下的Processor接口也可以通繼承 AbstractProcessor的方式實現Annotation處理器,一個處理器可以處理一種或者多種Annotation類型

 

與前面的Annotation通過反射來獲取信息不同 此處的Annotation處理器是通過RoundEnvironment 裏包含 一個getElementAnnotationWith()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章