内容大纲
- 常规范式——替代int保安全
- 高阶范式——实现单例模式
- 复杂范式——实现方法
- Android中的替代方案——IntDef/StringDef
- 纯 Java中的替代方案——MagicConstant
常规范式
- 取代int常量,确保类型安全性
可以看到,上例中,直接使用1,2之类的int值编译器是会报错的,因为enum是一种class,不止具有int值这一属性
相较于int值,enum会有类型安全检查,代码会更安全
高阶范式
- 实现单例模式
这样实现的单例模式,不需要处理线程同步的问题,相较于传统的懒汉-饿汉-doublecheck的优势显而易见
实际上单例模式特别容易导致内存泄露,应该尽量减少使用,用更易用的架构设计模式来避免使用单例模式
复杂范式
- 添加成员变量
在利用这一属性时,我们可以直接将enum当成一个类来使用,不一样的地方在于,enum的各项是直接给出了实例化的instance,所以带参构造函数需要我直接在定义中给出初始化参数(如上例中的hour)
- 提供有差异的API
如上图所示,DayType的两个类型,各自实现了free方法,实现了差异化的API,这一属性可以用于策略模式,针对不同的类型,我们的enum可以提供不同的策略算法,满足差异化的需求
- 实现接口
上面的抽象方法free,也可以抽象成接口形式,让枚举去实现,这一特性在工程中的应用极为有利,这样一来,就与我们的“面向接口编程”对上号了
注意API的访问级别需要升级为public
Android中的替代办法
我们都知道Android的内存非常宝贵,纵使enum有如此多的优点,但我们有时可能只想用它的一个替代int的属性,来增强代码的安全性,有没有其它更轻量的办法的?
答案是有的,@IntDef, @StringDef就能满足这一要求(属于注解范畴),以IntDef为例:
扒一扒IntDef的源码,我们会发现它其实自己也是一个注解,我们上例中应用的是它的value域,还可以利用的有flag域,鉴于flag一般都不会使用,不做过多介绍
Java模块中的替代办法
有的同学可能碰到这样的业务需要:
实际的工程是纯Java的,根本无法使用Android中的注解,这时该怎么办?
好吧,其实是我自己碰到这样的问题了,解决方案其实也很容易找到,查IntDef的设计思路,可以找到它的出处,最后的解决lib是
1 | org.intellij.lang.annotations.MagicConstant |
可以看到,这一lib是intellij的注解,感谢伟大的程序员们的杰作intellij
与IntDef不一样的地方在于:
- 需要添加intValues关键字,不可以省略(IntDef中对应的可省略关键字是value)
- 具体的值可以相同(IntDef中不可以)
- 值变为String类型时只需要改关键字为 stringValues
get
enum还有一些特性,比如ordinal()取值、初始值从0开始、用EnumSet/EnumMap代替序数
实际也不推荐使用(ordinal取值不确定性强,程序稳定性差,实在要使用可以用成员变量代替)