在Android开发中,我们经常需要定义一些限定范围的常量,通常我们会将这个范围取值定义为静态常量:
public class Constants {
public static final int SYSTEM_TYPE = 0;
public static final int TEXT_TYPE = 1;
public static final int IMG_TYPE = 2;
public static final int SOUND_TYPE = 3;
}
创建了一个setType方法,该方法需要接收参数(参数范围为这4种常量):
/**
* @param type 值为0:SYSTEM_TYPE, 1:TEXT_TYPE, 2:IMG_TYPE, 3:SOUND_TYPE
*/
public void setType(int type) {
//do some thing
}
这里有一个问题,就是调用setType的时候没法限制其传参范围:
public void main(String[] args) {
setType(Constans.TEXT_TYPE);
setType(10); //不会报错,编译会通过,但是没有对应的类型(10)来执行相应的逻辑
}
上面的setType方法没法限制入参范围,如果这个方法被别人调用,就可能导致入参错误的情况。
所以我们可以使用Enum枚举来解决这个问题,相信开发过Android的小伙伴们一定对Enum(枚举)不陌生吧。
首先定义一个枚举类:
public enum EnumType {
SYSTEM_TYPE,TEXT_TYPE,IMG_TYPE,SOUND_TYPE;
}
然后定义setType方法,入参为EnumType类型:
public void setType(EnumType type){ // 入参只能为枚举类中定义的类型
//do some thing
}
最后调用setType方法:
public void main(String[] args) {
setType(EnumType.IMG_TYPE);
setType(10); //报错
}
虽然这样解决了入参不明确的问题,但是使用枚举类,每一个枚举值都是一个对象,在使用它时会增加额外的内存消耗。官方文档也说明,安卓开发应避免使用Enum(枚举类),因为相比于静态常量,Enum会花费两倍以上的内存。
那么我们该怎么办才能既不使用Enum,又可以实现上面限制入参的效果呢?
在Android中可以使用@IntDef/@StringDef+自定义注解来替代Enum的作用。
首先自定义一个注解:
@IntDef({Type.SYSTEM_TYPE, Type.TEXT_TYPE, Type.IMG_TYPE, Type.SOUND_TYPE}) //限制入参范围
@Retention(RetentionPolicy.SOURCE) //设置注解保留级别为源码阶段
public @interface Type {
public static final int SYSTEM_TYPE = 0;
public static final int TEXT_TYPE = 1;
public static final int IMG_TYPE = 2;
public static final int SOUND_TYPE = 3;
}
定义setType方法,入参如下:
private void setType(@Type int type) {
//do some thing
}
最后调用setType方法如下:
public void main(String[] args) {
setType(Type.SYSTEM_TYPE);
setType(0); //报错
setType(10); //报错
}
@StringDef同理,就不再赘述了