好久沒有寫點(diǎn)什么了~。。。 計(jì)劃記錄一下java的注解和反射以及這兩個(gè)好基友的不可描述,這篇先記錄一下注解(Annotation)
java基礎(chǔ)之反射(Reflect)
注解的基本概念
定義:注解(Annotation),一種代碼級(jí)別的說明。它是JDK1.5及以后版本引入的一個(gè)特性,與類、接口、枚舉是在同一個(gè)層次。它可以聲明在包、類、字段、方法、局部變量、方法參數(shù)等的前面,用來(lái)對(duì)這些元素進(jìn)行說明,注釋。
Annotion(注解)是一個(gè)接口,程序可以通過反射來(lái)獲取指定程序元素的Annotion對(duì)象,然后通過Annotion對(duì)象來(lái)獲取注解里面的元數(shù)據(jù)。
需要注意的是,這里存在著一個(gè)基本的規(guī)則:Annotation不能影響程序代碼的執(zhí)行,無(wú)論增加、刪除 Annotation,代碼都始終如一的執(zhí)行。只有通過某種配套的工具才會(huì)對(duì)annotation類型中的信息進(jìn)行訪問和處理。從而間接影響程序的走向。
注解一般被用來(lái):
- 編寫文檔:通過代碼里標(biāo)識(shí)的注解生成文檔
- 代碼分析:通過代碼里標(biāo)識(shí)的注解對(duì)代碼進(jìn)行分析
- 編譯檢查:通過代碼里標(biāo)識(shí)的注解讓編譯器能夠?qū)崿F(xiàn)基本的編譯檢查
而我們?cè)谌粘i_發(fā)中常用的是上面的第二點(diǎn),自定定義注解并且對(duì)注解進(jìn)行解析。解析的過程一般是發(fā)生在運(yùn)行時(shí)。
內(nèi)置注解
javaSE中內(nèi)置的三個(gè)注解如下,都是熟面孔
@Override:它的作用是對(duì)覆蓋超類中方法的方法進(jìn)行標(biāo)記,如果被標(biāo)記的方法并沒有實(shí)際覆蓋超類中的方法,則編譯器會(huì)發(fā)出錯(cuò)誤警告。
@Deprecated:用于修飾已經(jīng)過時(shí)的方法;
@SuppressWarnings:用于通知java編譯器禁止特定的編譯警告。
其中SuppressWarnings在使用的時(shí)候需要設(shè)置參數(shù)值,比如:
@SuppressWarnings(value={ "rawtypes", "unchecked" })
由于SuppressWarnings annotation類型只定義了一個(gè)單一的成員,所以只有一個(gè)簡(jiǎn)單的value={...}作為name=value對(duì)。又由于成員值是一個(gè)數(shù)組,故使用大括號(hào)來(lái)聲明數(shù)組值。如下:
@SuppressWarnings({ "rawtypes", "unchecked" })
SuppressWarnings注解的常見參數(shù)值的簡(jiǎn)單說明:
- deprecation:使用了不贊成使用的類或方法時(shí)的警告;
- unchecked:執(zhí)行了未檢查的轉(zhuǎn)換時(shí)的警告,例如當(dāng)使用集合時(shí)沒有用泛型 (Generics) 來(lái)指定集合保存的類型;
- fallthrough:當(dāng) Switch 程序塊直接通往下一種情況而沒有 Break 時(shí)的警告;
- path:在類路徑、源文件路徑等中有不存在的路徑時(shí)的警告;
- serial:當(dāng)在可序列化的類上缺少 serialVersionUID 定義時(shí)的警告;
- finally:任何 finally 子句不能正常完成時(shí)的警告;
- all:關(guān)于以上所有情況的警告。
自定義注解
給注解準(zhǔn)備的注解——元注解
元注解的作用就是負(fù)責(zé)注解其他注解。Java5.0定義了4個(gè)標(biāo)準(zhǔn)的meta-annotation類型,它們被用來(lái)提供對(duì)其它 annotation類型作說明。
- @Documented —— 指明擁有這個(gè)注解的元素可以被javadoc此類的工具文檔化。這種類型應(yīng)該用于注解那些影響客戶使用帶注釋的元素聲明的類型。如果一種聲明使用Documented進(jìn)行注解,這種類型的注解被作為被標(biāo)注的程序成員的公共API。
- @Target——指明該類型的注解可以注解的程序元素的范圍。如果Target元注解沒有出現(xiàn),那么定義的注解可以應(yīng)用于程序的任何元素。
- CONSTRUCTOR:用于描述構(gòu)造器
- FIELD:用于描述域
- LOCAL_VARIABLE:用于描述局部變量
- METHOD:用于描述方法
- PACKAGE:用于描述包
- PARAMETER:用于描述參數(shù)
- TYPE:用于描述類、接口(包括注解類型) 或enum聲明
- @Inherited——指明該注解類型被自動(dòng)繼承。如果用戶在當(dāng)前類中查詢這個(gè)元注解類型并且當(dāng)前類的聲明中不包含這個(gè)元注解類型,那么也將自動(dòng)查詢當(dāng)前類的父類是否存在Inherited元注解,這個(gè)動(dòng)作將被重復(fù)執(zhí)行知道這個(gè)標(biāo)注類型被找到,或者是查詢到頂層的父類。
- @Retention——指明了該Annotation被保留的時(shí)間長(zhǎng)短。
- SOURCE:在源文件中有效(即源文件保留)
- CLASS:在class文件中有效(即class保留)
- RUNTIME:在運(yùn)行時(shí)有效(即運(yùn)行時(shí)保留)
創(chuàng)建自定義注解
定義注解格式:
public @interface 注解名 {定義體}
- 創(chuàng)建自定義注解和創(chuàng)建一個(gè)接口相似,但是注解的interface關(guān)鍵字需要以@符號(hào)開頭。
- 在定義注解時(shí),不能繼承其他的注解或接口。
- 聲明一個(gè)注解時(shí),其中的每一個(gè)方法實(shí)際上是聲明了一個(gè)配置參數(shù)。方法的名稱就是參數(shù)的名稱,返回值類型就是參數(shù)的類型(返回值類型只能是基本類型、Class、String、enum)??梢酝ㄟ^default來(lái)聲明參數(shù)的默認(rèn)值。
- 注解里面的參數(shù)只能用public或默認(rèn)(default)這兩個(gè)訪問權(quán)修飾.例如,String value();這里把方法設(shè)為defaul默認(rèn)類型
- 如果自定義注解時(shí)只有一個(gè)參數(shù)成員,最好把參數(shù)名稱設(shè)為"value",后加小括號(hào)例如:String value() default ""; 這樣在使用注解的時(shí)候可以不顯式的指定參數(shù)名稱。例如:@AnnotationName("valueString")
下面給一個(gè)自定義注解的栗子:
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Target(ElementType.METHOD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation{
/**
* 枚舉 狀態(tài)
*/
public enum Status{ SUCCESS,FAILED,NONE};
/**
* 顏色屬性
*/
Status testStatus() default Status.NONE;
String testString() default 'shli';
String testDate();
int testInt() default 1;
}
學(xué)會(huì)了如何自定義注解,但如果要發(fā)揮注解的作用,則在需要的地方添加自定義注解,并且在適當(dāng)?shù)牡胤綄?duì)注解進(jìn)行處理。
下一篇在記錄java反射機(jī)制的時(shí)候,將介紹對(duì)注解的處理。