第34条:用Enum代替int常量
枚举类型(enum type) 是指一组固定的常量组成合法值的类型,例如一年中的季节、太阳系中的行星或者一副牌中的花色
而在枚举产生之前,或者一些程序员的开发习惯,为了做一个区分度,通常会选择使用 int 类型的常量,如下:
public static final int DAY_MONDAY = 1;public static final int DAY_TUESDAY = 2;public static final int DAY_WEDNESDAY = 3;......public static final int ORANGE_NAVEL = 0;public static final int ORANGE_TEMPLE = 1;public static final int ORANGE_BLOOD = 2;
但是看这个标题也明白了,int 常量枚举的这种方式,会有很多的弊端:
- DAY_XXX 与 ORANGE_XXX 比较的时候,编译器和执行时都不会出现错误。
- 把 DAY_XXX 传入 需要一个 ORANGE_XXX 的方法中,编译器和执行时都不会出现错误。
- int 枚举是编译时异常,这个具体的 int 值会被编译到使用它们的客户端中,所以与这个 int 枚举类型关联的值发生了改变,必须重新编译,否则虽然程序还可以运行,但实际上,这个结果已经不太准确了。
- 想要打印一个 int 枚举很麻烦,而且就算打印出了,也只是显示一个数字,没有什么意义。
而 Java 后来创建了一个枚举类型的概念,格式如下:
public enum DAY {DAY_MONDAY,DAY_TUESDAY,......}public enum ORANGE {ORANGE_NAVEL,ORANGE_TEMPLE,ORANGE_BLOOD}
枚举类型就可以解决 int 常量枚举的问题
- 枚举类型定义了类的安全检查机制,例如当你的方法参数类型为枚举类型 DAY 的时候,那么它可以保证这个参数一定是这个 DAY 枚举类中的任何一个有效值(除了 null)。
- 同时通过 == 比较相等,或者赋值语句赋值的时候,都会去判断类型。
- 同时包含同名常量的多个枚举类型可以共存,因为每个类型有自己的命名空间,增加或重新排列枚举类型的常量,无需重新编译客户端的代码。
- 获取字符串直接 toString。
- 同时枚举类型的可读性也变强了,可以让开发人员对业务属性等有更好的熟悉和全貌的认识。
- 解决了硬编码问题。
第35条:用实例域代替序数(暂不常用,后期补充)
第36条:用EnumSet代替位域(暂不常用,后期补充)
第37条:用EnumMap代替序数索引(暂不常用,后期补充)
第38条:用接口模拟可扩展枚举(暂不常用,后期补充)
第39条:注解优先于命名模式
通过命名的方式来约定某种规范,其实往往不如通过注解的方式,注解的方式会更加清晰明确。
第40条:坚持使用@Override注解
这个注解表示,被注解的方法生命覆盖了超类型中的一个方法类型。而且@Override注解的生命周期是代码级,等生成字节码 class 文件的时候就没了。
第41条:用标记接口定义类型
例如 Serializable、Cloneable 等接口,进入源码后就会发现是一个空的接口,它仅仅作为一个标记,用来表明当前类或者接口符合某一种规范等,这就是标记接口的定义。
而标记注解,就是一种和标记接口很像的概念,注解中不包含任何成员,通过 isAnnotationPresent 方法来判断。
注:如果仅用于类或接口,可以优先考虑用接口标记的方式。如果需要作用于成员或方法,那只能使用注解标记。
