概要
Enum 是 java 中一种包含固定常数的类型,当我们需要预先定义一些值时,我们使用 Enum,这样做通常为了在编译时期避免接受额外常量引起的错误。
而且,Enum 增加了APK 的大小,比常量多5到10倍的内存占用,这是关于应用性能的最佳实践.
使用 Enum 的缺点
每一个枚举值都是一个对象,在使用它时会增加额外的内存消耗,所以枚举相比与 Integer 和 String 会占用更多的内存。
较多的使用 Enum 会增加 DEX 文件的大小,会造成运行时更多的开销,使我们的应用需要更多的空间。
如果你的应用使用很多的 Enum ,最好使用Integer 或 String 替代他们,但是这样还会有问题。
既然都说到这个份上了,那么有什么比较好的解决方法呢?
官方文档说明,安卓开发应避免使用Enum(枚举类),因为相比于静态常量Enum会花费两倍以上的内存。参考这里
那么如果需要使用Enum应该怎么做呢?
- 解决方案
既然是因为参数的类型太泛了造成的类型不安全,那么我只要将参数限定在某一个类型集合里面,就大功告成了,将@IntDef/@StringDef + @interface来进行限定参数。
使用
1.导入依赖
implementation 'com.android.support:support-annotations:25.1.0'
2.定义
public class MainActivity extends Activity {
//先定义 常量
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;
//用 @IntDef "包住" 常量;
// @Retention 定义策略
// 声明构造器
@IntDef({SUNDAY, MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY})
@Retention(RetentionPolicy.SOURCE)
public @interface WeekDays {}
@WeekDays int currentDay = SUNDAY;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setCurrentDay(WEDNESDAY);
//声明变量
@WeekDays int today = getCurrentDay();
switch (today){
case SUNDAY:
break;
case MONDAY:
break;
case TUESDAY:
break;
case WEDNESDAY:
break;
case THURSDAY:
break;
case FRIDAY:
break;
case SATURDAY:
break;
default:
break;
}
}
public void setCurrentDay(@WeekDays int currentDay) {
this.currentDay = currentDay;
}
@WeekDays
public int getCurrentDay() {
return currentDay;
}
}
public class EnumTest {
//定义常量
public static final int RED = 0;
public static final int GREEN = 1;
public static final int YELLOW = 2;
//用 @IntDef "包住" 常量
//定义注解
@IntDef({RED,GREEN,YELLOW})
@Retention(RetentionPolicy.SOURCE)
public @interface Led {}
//定义变量
@Led int red = 5;
//定义方法
@Led
public int getRed() {
return red;
}
}
flag=true 表示可以用条件进行位运算
@IntDef(flag = true, value = {ADD,SUB,MUL,DIV})
区别是第二种可以用条件进行位运算
总结
可以看到,如果不适用枚举,将会带来类型不安全的问题。一般情况下,我们在很多地方都会使用到枚举,因为方便和简洁。但是使用枚举也会产生占用内存过高等情况。所以我们可以有了自定义的方案,来限定我们使用的类型范围。