一辰妙、注解介紹
Java注解(Annotation)又稱 Java 標(biāo)注鹰祸。Java 語(yǔ)言中的類、方法密浑、變量蛙婴、參數(shù)和包等都可以被標(biāo)注。
1.1肴掷、注解寫法
格式:
@Target 注解標(biāo)注的目標(biāo):類敬锐、方法背传、變量呆瞻、參數(shù)和包等
@Retention 作用域:源碼、編譯時(shí)径玖、運(yùn)行時(shí)
public @interface 注解名稱{
屬性列表;
}
注解通過(guò) @interface 關(guān)鍵字進(jìn)行定義痴脾,如下,定義一個(gè)MyAnnotation的注解:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
int value() default -1;
String name();
}
@Target梳星、@Retention赞赖,也是元注解,元注解是可以注解到注解上的注解冤灾。
@Target
Target 目標(biāo)前域,限定注解了標(biāo)注的地方。取值如下:
- ElementType.ANNOTATION_TYPE 可以給一個(gè)注解進(jìn)行注解
- ElementType.CONSTRUCTOR 可以給構(gòu)造方法進(jìn)行注解
- ElementType.FIELD 可以給屬性進(jìn)行注解
- ElementType.LOCAL_VARIABLE 可以給局部變量進(jìn)行注解
- ElementType.METHOD 可以給方法進(jìn)行注解
- ElementType.PACKAGE 可以給一個(gè)包進(jìn)行注解
- ElementType.PARAMETER 可以給一個(gè)方法內(nèi)的參數(shù)進(jìn)行注解
- ElementType.TYPE 可以給一個(gè)類型進(jìn)行注解韵吨,比如類匿垄、接口、枚舉
@Target 可以給多個(gè)值,注解到多個(gè)地方椿疗,如
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
}
@Retention
Retention 英文意為保留漏峰,標(biāo)識(shí)注解作用域,在什么時(shí)候有效届榄。取值如下:
- RetentionPolicy.SOURCE 注解只在源碼階段保留浅乔,并被編譯器忽略。
- RetentionPolicy.CLASS 注解在源碼階段铝条、編譯器進(jìn)行編譯時(shí)保留靖苇,它并不會(huì)被加載到 JVM 中。
- RetentionPolicy.RUNTIME 注解在源碼階段攻晒、編譯器進(jìn)行編譯顾复、運(yùn)行時(shí)保留,運(yùn)行時(shí)鲁捏,它會(huì)被加載進(jìn)入到 JVM 中芯砸,所以在程序運(yùn)行時(shí)可以獲取到它們。
SOURCE < CLASS < RUNTIME给梅,即CLASS包含了SOURCE假丧,RUNTIME包含SOURCE、CLASS动羽。
@interface
定義注解時(shí)包帚,用@interface定義
注解的屬性
注解可以定義一些屬性,如value运吓、name:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
int value() default -1;
String name();
}
default 指定了默認(rèn)值
1.2渴邦、注解的使用
我們定義一個(gè)注解,簡(jiǎn)單的使用拘哨,如下:
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
int value() default -1;
}
//使用注解 MyAnnotation
public class MyAnnotationTest {
@MyAnnotation(value = 1)
private int age;
@MyAnnotation
private int age1;
......
}
Android元注解的使用
在Android中谋梭,系統(tǒng)源碼幫我們定了一些元注解,如:IntDef, LongDef, StringDef倦青,可以限定參數(shù)的取值范圍瓮床,可以減少使用枚舉,減少內(nèi)存产镐。
如隘庄,我們定義一個(gè)星期:
public static final int Sunday = 0;
public static final int Monday = 1;
public static final int Tuesday = 2;
public static final int Wednesday = 3;
public static final int Thursday = 4;
public static final int Friday = 5;
public static final int Saturday = 6;
再定義一個(gè)注解,限定使用這個(gè)注解時(shí)的取值癣亚,若不是限定的值丑掺,則源碼就會(huì)報(bào)紅:
@IntDef({Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday})
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.SOURCE)
public @interface Week {
}
注解Week的使用:
@Week
private static int weekDay = Saturday;
public static void setWeekDay(@Week int weekDay){
AnnotationUsageDemo.weekDay = weekDay;
}
public static void main(String[] args) {
//報(bào)紅,須使用:Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday
//setWeekDay(5);
//正確
setWeekDay(Friday);
}
不使用限定值述雾,報(bào)紅街州,如圖:
1.3蓬豁、注解的用法
注解單獨(dú)使用是沒(méi)有意義的,常見(jiàn)的用法:
- 注解+開(kāi)發(fā)工具(AS)菇肃,用于源碼期地粪,做一些代碼校驗(yàn)等,如注解:ResId琐谤、IntDef等
- 注解+APT 用于編譯期時(shí)生成一些代碼文件蟆技,如:butterknife、dagger2斗忌、hilt质礼、databinding
- 注解+字節(jié)碼操作 用于編譯時(shí)字節(jié)碼插樁,如:AspectJ织阳、ARounter眶蕉、CC
- 注解+反射 代碼運(yùn)行時(shí),通過(guò)反射唧躲,進(jìn)行相應(yīng)的處理造挽,如:XUtils、Lifecycle