Effective Java 2
五、枚举和注解
30、用enum代替int常量
132,135
31、用实例域代替序数
不要依赖于枚举的顺序编程
32、用EnumSet代替位域
33、用EnumMap代替序数索引
141
34、用接口模拟可伸缩的枚举
虽然无法编写可扩展的枚举类型,却可以通过编写接口以及实现该接口的基础枚举类型,对它进行模拟。
36、坚持使用Override注解
37、用标记接口定义类型
标记接口是没有包含方法声明的接口
六、方法
38、检查参数的有效性
非公有方法通常应该使用断言来检查它们的参数。
39、必要时进行保护性拷贝
比如:内部属性是不可变的日期类型,在第一次设值时,拷贝后赋值;读取值时,读取拷贝后的值,而不给原始对象。
41、慎用重载
重载机制很容易使期望落空。(一个方法调用可能有多个方法定义满足条件)
解决:使用像writeBoolean(boolean)、 writeInt(int)、writeLong(long)的方法定义
43、返回零长度的数组或集合,而不是null
如果方法返回null,而不是零长度的数组或集合,那调用方每次都要做null的判断,很麻烦。
Collections.emptySet、emptyList、emptyMap
七、通用程序设计
45、将局部变量的作用域最小化
46、for-each循环优先于传统的for循环
for-each循环在简洁性和预防bug方面有着传统for循环无法比拟的优势,而且没有性能损失。
47、了解和使用类库
应该把时间花在应用程序上,而不是底层的细节上。
必须掌握:java.lang,java.util,java.io,java.util.concurrent
48、如果需要精确的答案,请避免使用float和double
换算为整型int或用定点小数Decimal
49、基本类型优先于装箱基本类型
50、如果其他类型更适合,则尽量避免使用字符串(即不要滥用字符串)
字符串不适合代替枚举类型。
字符串不适合代替聚集类型。例如:appkey@adType,可以建一个类,来表示。
52、通过接口引用对象
53、接口优先于反射机制
55、谨慎地进行优化
不要去计较效率上的一些小小的得失,在97%的情况下,不成熟的优化才是一切问题的根源。
不要费力去编写快速的程序——应该努力编写好的程序,速度自然会随之而来。
九、并发
68、executor和task优先于线程
不仅应该尽量不要编写自己的工作队列,而且还应该尽量不直接使用线程。
线程是既充当工作单元,又是执行机制。现在是把工作单元和执行机制分开。工作单元是任务,执行机制是线程池。
69、并发工具优先于wait和notify
并发工具:ConcurrentMap,BlockingQueue,同步器CountDownLatch
71、慎用延迟初始化
对于延迟初始化,最好建议“除非绝对必要,否则就不要这么做”。
十、序列化
74、谨慎的实现Serializable接口
如果没有声明一个显示的序列版本UID,兼容性将会遭到破坏,在运行时导致InvalidClassException异常。