34. 用enum代替int常量
每当需要一组固定常量,并且在编译时就知道其成员的时候,就应该使用枚举。如果多个枚举常量同时共享相同的行为时,可考虑策略枚举。
34.1 int常量的缺点
int常量只是数字,描述性差。int常量不具有类型安全性,常量混用没有警告。int常量是编译时常量,如果关联值发生了变化,客户端必须重新编译。
34.2 枚举类型的优势
a. 可读性好。也可以打印可读的文字描述,方便调试。
b. 更加安全。不可实例化,是类型安全的,不同枚举不能混用。
c. 功能更强大。允许添加接口,方法和数据域。
34.3 枚举的缺点是装载和初始化时需要时间和空间的成本,但较小。
34.4 应该避免在枚举内部使用swtich语句(不利于维护,常量集会发生变化)。枚举中的swtich语句适合于给外部的枚举类型增加特定于常量行为。
35. 用实例域代替序数
永远不要根据枚举的序数导出与它关联的值,而是要将它保存在一个实例(数据)域中。最好完全避免使用ordinal方法。
36. 用EnumSet代替位域
需要位运算时,考虑用EnumSet。EnumSet集位域的简洁和性能优势及枚举类型的所有优点。
37. 用EnumMap代替序数索引
最好不要用序数来索引数组(即ordinal作Map的key),而要用EnumMap。如果表示的关系是多维的,就使用EnumMap<...,EnumMap<...>>。
38. 用接口模拟可扩展的枚举
虽然无法编写可扩展的枚举类型,却可以通过编写接口以及实现该接口的基础枚举类型来对它进行模拟。
39. 注解优先于命名模式
39.1 命名模式的缺点
a. 文字拼写错误会导致失败,且没有任何提示。
b. 无法确保它们只用于相应的程序元素上。
c. 没有提供将参数值与程序元素关联起来的好方法。
39.2 注解解决了命名模式的所有缺点
有了注解,完全没有理由再使用命名模式了。所有的程序员都应该使用Java平台提供的预定义的注解类型。
可重复注解(@Repeatable)可以提升代码的可读性,但是注意处理可重复注解容易出错。
40. 坚持使用Override注解
在想要的每个方法声明中使用Override注解来覆盖超类声明,编译器可以替你防止大量错误。
41. 用标记接口定义类型
标记接口(marker interface)是不包含方法声明的接口,它只是指明(或标明)一个类实现了具有某种属性(数据)的接口。标记注解(marker annotation)就是使用注解,“标注”被注解的元素。
标记接口有两点胜过标记注解:
a. 标记接口定义的类型是由被标记类的实例实现的;标记注解则没有定义这样的类型。
b. 标记接口可以被更加精确地进行锁定。
标记注解的优点在于它们是更大的注解机制的一部分。如果标记是应用于任何程序元素而不是类或者接口,或者用于使用了注解类型的框架。就必须使用注解。如果标记只应用于类或者接口,就应该优先使用标记接口。