概要
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})
区别是第二种可以用条件进行位运算
总结
可以看到,如果不适用枚举,将会带来类型不安全的问题。一般情况下,我们在很多地方都会使用到枚举,因为方便和简洁。但是使用枚举也会产生占用内存过高等情况。所以我们可以有了自定义的方案,来限定我们使用的类型范围。