關(guān)于java Annotation
什么是注解(Annotation)
java注解是附加在代碼中的一些元信息,用于一些工具在編譯、運行時
進行解析和使用,起到說明、配置的功能,注解不會影響到代碼的實際
邏輯,僅僅是起到輔助性的作用。包含在java.lang.annotation中。
注解的組成
注解包含元注解和普通注解,所謂元注解是修飾注解的注解。
主要的元注解有@Retention、@Documented、@Target、@Inherited,下面逐一介紹。
(1)@Retention 表明的是注解的聲明周期。注解的值是enum類型的
RetentionPolicy。包括以下幾種情況。
①SOURCE:注解只保留在源文件。當Java被解析成class文件的時
候, 注解被遺棄。Annotations are to be discarded by the compiler
②CLASS:注解保留到class文件中,但是當class文件被JVM加載的
時候被遺棄。這是默認的聲明周期
③RUNTIME:注解被保留到class文件中、class文件被JVM加載的時 候,能通過反射被獲取
(2)@Documented:表示注解是否能被 javadoc 處理并保留在文檔 中。
(3)@Taeget:表明該注解類型適用的程序元素。如果meta-annotation
Target沒有出現(xiàn)在注解類型的聲明中,則表示這個注解類型可以使用在
任何程序元素。但是,如果Target使用在特定的程序元素 中,則編譯器
會執(zhí)行指定的使用限制。主要的ElementType包括:
①Type:包括Class,interface(包括注解類型),枚舉聲明
②FIELD:域(包括枚舉常量)
③METHOD:方法
④PARAMETER:參數(shù)
⑤CONSTRUCTOR:構(gòu)造器
⑥LOCAL_VARIABLE:本地變量
⑦ANNOTATION_TYPE:注解類型,用這個修飾的話,表明該注解是元注解
⑧PACKAGE:包
(4)@Inherited:表明該注解類型是可繼承的。如果一個可繼承的元注
解出現(xiàn)在一個注解類型的聲明中,把該注解使用在class上,class沒有
使用該注解類型,然后將在類的超類中查詢是否使用該注解類型。程序
會一直進行,直到注解類型被找到或者已經(jīng)達到了最頂層的類-
Object。如果沒有包含該注解類型的超類,則會判定該類沒有使用該注解類型。
自定義注解的語法以及定義形式
使用@Interface自定義注解時,自動繼承了java.lang.annotation.Annotation接口,由編譯程序自動完成其他細節(jié)。在定義注解時,不能繼承其他的注解或接口,@Interface用來聲明一個注解,其中的每一個方法實際上是聲明了一個配置參數(shù),方法的名稱是參數(shù)的名稱,返回值類型是參數(shù)的類型,返回值類型只能是基本類型、Class、String、enum??梢酝ㄟ^default來聲明參數(shù)的默認值。
定義注解格式:
public @Interface 注解名{定義體}
(1)以@Interface方式定義
(2)注解包含成員,成員是以無參數(shù)的方法的形式被定義。例如:String value();
(3)成員的權(quán)限訪問級別有兩種,分別是public或默認。如果沒有表示public,就是默認。
(4)返回值可以是以下值:
①基本數(shù)據(jù)類型:int,float,boolean,byte,double,char,long,short
②String類型
③enum枚舉類型
④Clas類型
⑤Annotation類型
⑥以上所有類型的數(shù)組
(5)注解類型需要表明注解的生命周期、作用的程序元素、是否可繼承
等等,這些信息都是通過元注解實現(xiàn)。
(6)成員賦值是通過@Annotation(name=value),如果成員方法的名字
為value,則可以直接通過@Annotation(value)賦值
具體可以看下面的實例,元注解Target的源碼實現(xiàn):
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = { ElementType.ANNOTATION_TYPE } )
public @interface Target
{
ElementType[] value();
}
注解實例
食物名稱注解:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface FoodName {
String value() default "";
}
食物顏色注解:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface FoodColor {
public enum foodColor {BLUE, RED, WHITE,BLACK};
public foodColor color() default foodColor.RED;
}
供應(yīng)商注解:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Provider {
int providerNO() default -1;
String providerNmame() default "";
String providerAddress() default "";
}
注解解析類:
public class foodUtils {
public void getFruit(Class<?> clazz){
Field[] fields=clazz.getFields();
for(Field field:fields){
if(field.isAnnotationPresent(FoodName.class)){
FoodName fruitName=field.getAnnotation(FoodName.class);
String FruitName=fruitName.value();
System.out.println("食物名稱:"+FruitName);
}
if(field.isAnnotationPresent(FoodColor.class)){
FoodColor fruitColor=field.getAnnotation(FoodColor.class);
String Color=fruitColor.color().toString();
System.out.println("食物顏色:"+Color);
}
if (field.isAnnotationPresent(Provider.class)){
Provider provider=field.getAnnotation(Provider.class);
int providerNo=provider.providerNO();
String providerName=provider.providerNmame();
String providerAddress=provider.providerAddress();
System.out.println("提供商編號:"+providerNo+",提供商名稱:"+providerName+",提供商地址:"+providerAddress);
}
}
}
}
測試類:
public class test {
public static void main(String[] args){
foodUtils fruitUtils=new foodUtils();
fruitUtils.getFruit(Chocolate.class);
}
}
結(jié)果輸出:
食物名稱:chocolate
食物顏色:BLACK
提供商編號:1,提供商名稱:浙商集團,提供商地址:浙江杭州