【effective java】30~37.枚举和注解

第30条:用enum代替int常量
a)int常量的缺点

public static final int APPLE_FUJI = 0;
public static final int APPLE_PIPPIN = 1;
public static final int APPLE_GRANNY_SMITH = 2;

public static final int ORANGE_NAVEL = 0;
public static final int ORANGE_TEMPLE = 1;
public static final int ORANGE_BLOOD = 2;

(1)将apple传到想要orange的方法中,不会出现错误
(2)用==操作符将apple与orange比较,不会出现错误
(3)int枚举是编译时常量,被编译到客户端中,如果枚举常量关联的int发生变化,客户端必须重新编译,如果没有重新编译,程序仍可以运行,但行为就确定了,如APPLE_FUJI关联的常量不再是0,而是3。
(4)将int枚举常量翻译成可打印的字符串很麻烦
(5)遍历一个组中所有的int枚举常量,获得int枚举组的大小,没有可靠的方法,如想知道APPLE的常量有多少个,除了查看int枚举常量所在位置的代码外,别无他法,而且靠的是观察APPLE_前缀有多少个,不可靠

b)枚举:类型安全性、使用方便性

public enum Apple {FUJI, PIPPIN, GRANNY_SMITH}
public enum Orange {NAVEL, TEMPLE, BLOOD}

第31条:用实例域代替序数
序数ordinal(),大多数人不需要用到ordinal这个方法,也不能把这个当做枚举的值;要用自己写的值来标记枚举的唯一值

第32条:用EnumSet代替位域
EnumSet底层是用位向量实现的。

应用场景:在一些工作中,比如医生、客服,不是每个工作人员每天都在的,每个人可工作的时间是不一样的,比如张三可能是周一和周三,李四可能是周四和周六,给定每个人可工作的时间,我们可能有一些问题需要回答,比如:
有没有哪天一个人都不会来?
有哪些天至少会有一个人来?
有哪些天至少会有两个人来?
有哪些天所有人都会来,以便开会?
哪些人周一和周二都会来?
代码实现:https://gitee.com/charjay/effective.git

第33条:用EnumMap代替序数索引
EnumMap在运行速度方面之所以能与通过序数索引的数组相媲美,是因为EnumMap在内部使用了这种数组

应用场景:固体、液体、气体之间的转换
代码实现:https://gitee.com/charjay/effective.git

第34条:用接口模拟可伸缩的枚举
枚举类型是不可扩展的,但是接口类型是可扩展的。使用接口,可以模拟可伸缩的枚举。
接口模拟可伸缩枚举的不足:无法实现从一个枚举继承到另一个枚举,所以有些公共的功能是在每个枚举类中重复的。如果公共的功能比较多,将它封装到一个辅助类或静态辅助方法中,来避免代码的复制工作。
代码实现:https://gitee.com/charjay/effective.git

第35条:注解优先于命名模式
例如:早期JUnit测试框架要求用户一定要用test作为测试方法名称的开头,这时候如果用户的测试方法名不是test就报错了,这时候注解就出来了,只要加一个@Test注解,而不管方法名

第36条:坚持使用Override注解
如果在你想要的每个方法声明中使用 Override 注解来覆盖超类声明 , 编译器可以替你防止大量错误 . 在具体的类中 , 不必标注你确信覆盖了抽象方法声明的方法(标注也可)

第37条:用标记接口定义类型
本节主要比较标记注解和标记接口
标记接口: 指接口中没有包含方法声明 , 而只是指明一个类实现了具有某种属性的接口
标记注解: 标记注解是特殊类型的注解,其中不包含成员。标记注解的唯一目的就是标记声明,因此,这种注解作为注解而存在的理由是充分的。确定标记注解是否存在的最好方式是使用isAnnotationPresent()方法,该方法是由AnnotatedElement接口定义的。

标记注解使用的频率大大高于标记接口 , 我们来看看它究竟优秀在哪里
1.标记注解可以通过默认的方式添加一个或者多个注解类型元素 , 给已被实用的注解类型添加更多地信息 .
2.标记注解是更大注解机制的一部分 , 这意味这它在那些支持注解作为编程元素之一的框架中同样具有一致性

即使现在标记注解已经接近可以替换掉标机接口 , 但标记接口相比于标记注解依然有它的优势
1.标机接口定义的类型是由被标记类的实例实现的 ; 标记注解则没有定义这样的类型 . 这个类型允许你在编译时捕捉在使用标记注解的情况下要到运行时才能捕捉到的错误 .
2.标记接口可以更加精确地进行锁定

总之 , 标记接口和标记注解各有用处 . 如果想要定义一个任何新方法都不会与之关联的类型 , 标记接口就是最好的选择 . 如果想要标记程序元素而非类和接口 , 考虑到未来可能要给标记添加更多地信息 , 或者标记要适合于已经广泛使用了注解类型的框架 , 那么标记注解是正确的选择

猜你喜欢

转载自blog.csdn.net/charjay_lin/article/details/81083799
今日推荐