最近看別人的代碼,發現別人使用了@IntDef的注解,便上網搜了一圈記錄下來。
定義
Google文檔是這樣說的
Use the @IntDef and @StringDef annotations so you can create enumerated annotations of integer and string sets to validate other types of code references. Typedef annotations ensure that a particular parameter, return value, or field references a specific set of constants. They also enable code completion to automatically offer the allowed constants.
就是可以通過@IntDef和@StringDef創建枚舉注解來驗證你的代碼引用是否正確,編譯器自動檢查也會對此校驗。
使用
一般我們用靜態常量來替代枚舉,比如一年四季,一周七天,九大行星,七大洲等這些固定的值:
public static final int SPRING = 1;
public static final int SUMMER = 2;
public static final int AUTUMN = 3;
public static final int WINTER = 4;
但是這樣寫有些小問題,設置季節的時候可以設置任意int值,導致程序的健壯性不是很好。所以就引出了枚舉:
enum Season {
SPRING, SUMMER, AUTUMN, WINTER
}
這樣setSeason()就不會設置成其他值,只能是枚舉中的其中一個值。
但是各種Android性能優化告訴我們,盡量少用枚舉,枚舉消耗的內存比定義成常量更多。(其實少用點枚舉也沒多大關系,只有在內存緊張的時候才會考慮),因此,谷歌就推出了@IntDef和@StringDef注解。
首先,加入依賴:
compile 'com.android.support:support-annotations:22.0.0'
然后,定義靜態常量:
public static final int SPRING = 1;
public static final int SUMMER = 2;
public static final int AUTUMN = 3;
public static final int WINTER = 4;
為這些常量聲明@IntDef:
@IntDef({SPRING, SUMMER,AUTUMN,WINTER})
@Retention(RetentionPolicy.SOURCE)
public @interface Season {}
@Retention是Java里的注解內容,用于指定被修飾的Annotation可以保留多長時間:
- RetentionPolicy.CLASS 默認值,編譯器將把Annotation記錄在class文件中。當運行Java程序時,JVM不再保留Annotation。
- RetentionPolicy.RUNTIME 編譯器將把Annotation記錄在class文件中。當運行Java程序時,JVM也會保留Annotation。程序可以通過反射獲取該Annotation信息。
- RetentionPolicy.SOURCE Annotation只保留在源代碼中,編譯器直接丟棄這種Annotation。
接下來我們使用的時候:
@Season int currentDay ;
public void setCurrentDay(@Season int currentDay) {
this.currentDay = currentDay;
}
@Season
public int getCurrentDay() {
return currentDay;
}
這樣就完成了,既不用枚舉,常量也不會亂定義的問題。@StringDef用法一樣,就是常量定義的是String類型。