[读书笔记]Effective Java Ch6: 枚举与注解

个人认为本章比较重要的有下面几个Item:

  • Item 30:  使用enum代替int
  • Item 32: 使用EnumSet 代替bit field
  • Item 35: 注解优先于命名模式

其他几个Item可能学习不是那么深刻,并没深入记录。

本文原创, 原文地址:http://www.flyml.net/2017/03/09/effective-java-ch6-enum-annotation


 

Item 30: 使用enum代替int (Enum初步介绍)

虽然直译过来是”使用enum代替int”, 但是这一小节实际上就是对enum的一个初步介绍

反例:

 

上面这种方式非常不推荐, 比如命名空间是通过前缀,APPLE_ORANGE_,几乎没有任何安全性可言。

比如, APPLE_GRANNY_SMITH = ORANGE_BLOOD 在编译跟运行的时候,不会有任何错误提示。 错误的排查也会很复杂。这种模式叫做int enum pattern

相应的, 可以将其改造成String enum patternString模式),

 

虽然可以解决他们的值没有意义的问题, 但是性能上面会比较差,因为基础是字符串比较。同时依然不能比较命名空间的问题。

比较推荐的方法,使用enum:

 

另外顺便提一下枚举类型的两个比较有用的特性:

  1. 支持默认值,并且默认值还可以是多个。比如:

     

    注意: 这里的构造函数跟普通类的构造函数有点区别, 第7行的someOtherVal 是一个测试的属性, 并且虽然不需要但是在初始化的时候(即构造函数之中)

    这也是很自然的事情, 因为枚举类型是不可变的类型

  2. 还可以定义相应的操作/函数

     

     

  3. 自带一些比较好用的方法
    1. Planet.values()这个方法自动获取了所有值
    2. valueOf()从字符串转到相应的枚举类型的值

       

       

  4. 策略枚举(Strategy Enum)这真心是一个比较复杂的例子。。。

     

    这是在一个Enum之中又嵌套了一个Enum

     

本文原创, 原文地址:http://www.flyml.net/2017/03/09/effective-java-ch6-enum-annotation

Item 31: Use instance fields instead of ordinals

在Enum 之中有一个自带的方法ordinal(), 返回这个值的顺序。

但是非常不推荐使用这个值作为值默认的值。 宁愿麻烦一点人工写出来,否则后期的维护会很痛苦, 因为谁也不知道会不会调整Enum之中的值的顺序。

Item 32 : 使用EnumSet 代替bit field

很多时候, 我们在JDK或者C++之中都能看到类似下面的做法:

 

使用的时候,就像下面这样:

 

即: 通过位运算的方式来进行操作。

这种方法看起来比较高级, 问题也不是特别大, 但是灵活性还是不够好。 比较推荐使用EnumSet的方式来代替, 参考下面的代码:

 

注意: 上面的applyStyles()方法的参数变成了一个Set。这样操作起来就清晰很多了~

在调用的时候, 也很清晰:

 

EnumSet是JDK自带的一个类。

本文原创, 原文地址:http://www.flyml.net/2017/03/09/effective-java-ch6-enum-annotation

Item 33 : 使用EnumMap 代替ordinal值

PS: 脑海之中回顾了一下, 感觉目前并没有太多的使用EnumMap的场景。 贴一个看起来更容易懂的使用示例:

参考自:http://www.cnblogs.com/chenpi/archive/2016/03/19/5296330.html

 

Item 35: 注解优先于命名模式

命名模式一个典型的应用就是在JUnit之中, 如果方法以 test开头就属于单元测试。这种模式, 如果一不小心写错了字, 要发现就很麻烦,维护起来也很危险。

比较推荐的方法是使用注解, 即增加一个 @Test 的注解,告诉Junit这是一个单元测试方法。

其他的没有细细看懂。。。

Item 36: 坚持使用Override注解

记住就好, 本身并没有太多要说的。。。

本文原创, 原文地址:http://www.flyml.net/2017/03/09/effective-java-ch6-enum-annotation

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注