[笔记]《Effective Java》
刚入手了这本书. 列个目录. 仅仅目录信息量就很大了...偶尔翻翻感兴趣的条目.
【√】为已掌握
第2章 创建和销毁对象
http://www.cnblogs.com/stephen-liu74/archive/2012/01/13/2228354.html
第1条: 考虑用静态工厂方法代替构造器
第2条: 遇到多个构造参数时要考虑用构建器(Builder模式)
第3条: 用私有构造器或者枚举类型强化Singleton属性
第4条: 通过私有构造器强化不可实例化的能力【√】
针对: 只包含静态方法和静态域的类, 一般是工具类(utility class)
实例化没有意义
注意点: 要使类的外部和内部都不能实例化这个类.
怎么做? 将构造器设置为private, 这样类的外部将无法实例化该类, 与此同时, 在这个私有的构造函数的实现中直接抛出异常, 从而避免不小心在类的内部调用构造器.
// Noninstantiable utility class
public class UtilityClass {
// Suppress default constructor for noninstantiability
private UtilityClass() {
throw new AssertionError();
}
}
副作用: 该类不能被子类化.
如果想要继承上面的UtilityClass类, 会得到错误提示:
Implicit super constructor UtilityClass() is not visible. Must explicitly invoke another constructor.
为什么? 所有的构造器都必须显式或隐式地调用超类(superclass)构造器.
第5条: 避免创建不必要的对象
第6条: 消除过期的对象引用
第7条: 避免使用终结方法
第3章 对象通用方法
http://www.cnblogs.com/stephen-liu74/archive/2012/01/16/2228360.html
第8条: 覆盖equals时请遵守通用约定
第9条: 覆盖equals时总要覆盖hashCode
第10条: 始终要覆盖toString
要考虑的问题: 是否在文档中指定返回值的格式.
第11条: 谨慎地覆盖clone
第12条: 考虑实现Comparable接口
第4章 类和接口
http://www.cnblogs.com/stephen-liu74/archive/2012/01/18/2228349.html
第13条: 使类和成员的可访问性最小化
第14条: 在公有类中使用访问方法而非公有域
第15条: 使可变性最小化
第16条: 复合优先于继承
第17条: 要么为继承而设计,并提供文档说明,要么就禁止继承
第18条: 接口优先于抽象类【*】
关键原因: Java是不支持多重继承但是可以实现多个接口的.
- 现有的类可以很容易被更新, 以实现新的接口.
- 接口是定义mixin(混合类型)的理想选择.【Comparable是一个典型的mixin接口】
- 接口允许我们构造非层次结构的类型框架.
可以为接口提供一个抽象的骨架实现(skeletal implementation)类.【AbstractInterface】
第19条: 接口只用于定义类型
常量接口模式是对接口的不良使用.
应该使用枚举类型(enum type)或工具类(utility class)
第20条: 类层次优于标签类
第21条: 用函数对象表示策略
第22条: 优先考虑静态成员类
第5章 泛型
http://www.cnblogs.com/stephen-liu74/archive/2012/01/20/2228938.html
第23条: 请不要在新代码中使用原生态类型
第24条: 消除非受检警告
第25条: 列表优先于数组
第26条: 优先考虑泛型
第27条: 优先考虑泛型方法
第28条: 利用有限制通配符来提升API的灵活性
第29条: 优先考虑类型安全的异构容器
第6章 枚举和注解
http://www.cnblogs.com/stephen-liu74/archive/2012/01/23/2232218.html
第30条: 用enum代替int常量
第31条: 用实例域代替序数
第32条: 用EnumSet代替位域
第33条: 用EnumMap代替序数索引
第34条: 用接口模拟可伸缩的枚举
第35条: 注解优先于命名模式
第36条: 坚持使用Override注解
第37条: 用标记接口定义类型
第7章 方法
http://www.cnblogs.com/stephen-liu74/archive/2012/01/25/2245971.html
第38条: 检查参数的有效性
第39条: 必要时进行保护性拷贝
第40条: 谨慎设计方法签名
第41条: 谨慎重载
第42条: 慎用可变参数
第43条: 返回零长度的数组或者集合, 而不是null【√】
【没注意的话, 确实经常会使用返回null的方式. 然后在前端再判断是否为null. 导致前端许多判断是否为null的语句. 如果只是返回对象而不是数组或集合呢?】
返回null的坏处: 客户端中必须有额外的代码来处理null返回值.【判断是否为null】
正确的做法:
// The right way to return an array from a collection
private final List<Cheese> cheesesInStock = ...;
private static final Cheese[] EMPTY_CHEESE_ARRAY = new Cheese[0];
/**
* @return an array containing all of the cheeses in the shop.
*/
public Cheese[] getCheeses() {
return cheesesInStock.toArray(EMPTY-CHEESE_ARRAY);
}
对于空集合, 使用Collections.emptySet()
、Collections.emptyList()
和Collections.emptyMap()
.
// The right way to return a copy of a collection
publlic List<Cheese> getCheeseList() {
if (cheesesInStock.isEmpty())
return Collections.emptyList(); // Always returns same list
else
return new ArrayList<Cheese>(cheesesInStock);
}
第44条: 为所有导出的API元素编写文档注释
第8章 通用程序设计
http://www.cnblogs.com/stephen-liu74/archive/2012/01/27/2261576.html
第45条: 将局部变量的作用域最小化
第46条: for-each循环优先于传统的for循环
第47条: 了解和使用类库
第48条: 如果需要精确的答案,请避免使用float和double
第49条: 基本类型优先于基本装箱类型
第50条: 如果其他类型更适合, 则尽量避免使用字符串
第51条: 当心字符串连接的性能
第52条: 通过接口引用对象
第53条: 接口优先于反射机制
第54条: 谨慎地使用本地方法
第55条: 谨慎地进行优化
第56条: 遵守普遍接受的命名惯例
第9章 异常
http://www.cnblogs.com/stephen-liu74/archive/2012/01/30/2263585.html
第57条: 只针对异常情况才使用异常
第58条: 对可恢复的情况使用受检异常,对编程错误使用运行时异常
第59条: 避免不必要的使用受检异常
第60条: 优先使用标准异常
第61条: 抛出与抽象相对应的异常
第62条: 每个方法抛出的异常都要有文档
第63条: 在细节中包含能捕获失败的信息
第64条: 努力使失败保持原子性
第65条: 不要忽略异常
第10章 并发
http://www.cnblogs.com/stephen-liu74/archive/2012/02/01/2270868.html
第66条: 同步访问共享的可变数据
第67条: 避免过度同步
第68条: executor和task优先于线程
第69条: 并发工具优先于wait和notify
第70条: 线程安全性的文档化
第71条: 慎用延迟初始化
第72条: 不要依赖于线程调度器
第73条: 避免使用线程组
第11章 序列化
http://www.cnblogs.com/stephen-liu74/archive/2012/02/03/2284306.html