关于Android中使用Enum的一点总结

枚举是Java 1.5版本增加的特性,枚举是指由一组固定的常量组成的合法值的类型,在还没有引入枚举的时候,为了表示枚举类型我们常用的方法是声明一组静态int 常量。在Effective Java中作者分析了这种模式的许多脆弱之处,因此推荐使用枚举来代替静态常量方案。

Effective Java中列举了使用枚举的的优点:

  1. 枚举提供了编译时的类型安全;
  2. 包含同名常量的多个枚举类型可以在一个系统中和平共处;
  3. 允许添加任意的方法和域,并实现任意的接口,枚举提供了所有Object方法的高级实现,并实现了Comparable和Serializable接口。

但是最近在浏览Google的官方文档的时候发现,Google是并不不推荐在Android中使用枚举的。

Google的的依据是:

  1. 枚举通常会比静态常量多使用超过一倍的内存;
  2. 在每一个类(包括匿名内部类)中多生成500byte的.class的文件;
  3. 每一个类的实例有12-16个字节的RAM开销;

总结一下:
枚举相对静态常量最大的有点在于编译时类型安全,但是内存开销比使用静态常量大。

Google为了弥补静态常量的缺陷,提出了使用IntDef 和StringDef两个注解来提供编译时的类型安全

首先引入依赖:

compile 'com.android.support:support-annotations:24.1.1'

以@IntDef为例的使用方法:

 public class MainActivity extends AppCompatActivity {
        //声明静态常量
        public static final int MERCURY = 0;
        public static final int VENUS = 1;
        public static final int EARTH = 2;
        public static final int MARS = 3;
        public static final int JUPITER = 4;
        public static final int SATURN = 5;
        public static final int URANUS = 6;
        public static final int NEPTUNE = 7;

        //用一个@IntDef({})将其全部变量包含,其次需要一个Retention声明其保留级别,最后定义其接口名称
        @IntDef({MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE})
        @Retention(RetentionPolicy.SOURCE)
        public @interface Planet {
        }

        @Planet
        int currentPlanet;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            @Planet int planet = getCurrentPlanet();
            switch (planet) {
                case MERCURY:
                    break;
                case VENUS:
                    break;
                case EARTH:
                    break;
                case MARS:
                    break;
                case JUPITER:
                    break;
                case SATURN:
                    break;
                case URANUS:
                    break;
                case NEPTUNE:
                    break;
                default:
                    break;
            }
            //传个8  有错误提示
            //setCurrentPlanet(8);
        }

        //只要一个变量使用了@Planet注解,那么他的值必须属于Planet
        public void setCurrentPlanet(@Planet int currentPlanet) {
            this.currentPlanet = currentPlanet;
        }

        @Planet
        private int getCurrentPlanet() {
            //如果返回值不属于Planet,那么编译器会提示错误 保证了编译时安全
            return currentPlanet;
        }
    }

你可能感兴趣的:(关于Android中使用Enum的一点总结)