使用@IntDef和@StringDef代替Java枚举
最近看别人的代码,发现别人使用了@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类型。
参考
上一篇: 最小生成树--Kruskal
下一篇: volume container