【第21条】用类来代替enum结构
要先说明一下:本书写作于2001年,正值作者参与建设JDK1.4的时期。后来到了JDK1.5,Java又将抛弃了多年的enum枚举重拾了起来。所以本条是在没有enum的时候写的。
?
??? JDK1.4及以前版本省略了enum。其实enum也是一种struct,我们当然是用class来代替之,但为什么又要单独作为一条来讲呢?是因为用类来替代枚举的时候,比较容易(或者说事实中绝大多数人都已经)犯一些错误。
?
??? 比如我们要一个有三种颜色的Color,有人会定义为
if (dotA.color.equals(Color.RED)) { // 前提:dotA的实现类中,color的类型既不是int也不是String,而是Color ......}?
??? 我们看到了两大好处。再看看JDK1.5提供的enum关键字(它对应一个类Enum),从使用方法和特征来说,类型安全枚举模式和JDK1.5的enum枚举是非常相似的。那么在没有枚举的年代,作者尚且建议我们使用类型安全枚举模式,如今有了enum,我们就更没有理由拒绝它了。
?
??? 但是,类型安全枚举模式和enum枚举就没有弱点吗?当然不是,首当其冲的就是刚才提到的,当常量组非常多的时候,使用N多的类型安全枚举模式或enum枚举,可能是一件让人头痛的事情。也许你会因为这一点而一票否决了它。
?
??? 再有就是如果对应枚举中项目的值(如前例中的dotA.color)将要保存到数据库或外部文件时,势必要用一个int或String来代表之,为此可能要在类型安全枚举类中增加一个private value,然后toString方法返回这个value的String形式;或者在enum中定义抽象方法(类似toString)。但这也可能导致toString方法的滥用,而失去“类型安全”的保护。
?
??? 最后,当类型安全枚举模式的类(没有研究enum枚举可否)实现了序列化后,如果期待不同版本程序序列化出来的字符流可以相互反序列化,那么后续版本就只能够在原来的最后面追加元素。(当然这一点对于int型和String型常量类也是一样的,而且还可能更糟)
?
??? 本来还想好好研究一下enum,但是,刚刚得知稍后要进行的公司羽毛球比赛被抽到的下下签,没有心情了,以后再说吧。今天的笔记就写到这儿了。
?
?
?
【Effective Java 学习笔记】系列连载专题请见:
http://tonylian.iteye.com/categories/64208
?