[笔记]《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

第74条: 谨慎地实现Serializable接口

第75条: 考虑使用自定义的序列化形式

第76条: 保护性的编写readObject方法

第77条: 对于实例控制, 枚举类型优先于readResolve

第78条: 考虑用序列化代理代替序列化实例


[设计模式] 组合模式

COMPOSITE(组合) —— 对象结构型模式


[设计模式] 迭代器模式

ITERATOR(迭代器) —— 对象行为型模式


[设计模式] 策略模式

STRATEGY(策略) —— 对象行为型模式


[设计模式] Facade

Facade


[设计模式] 职责链模式

职责链模式


[笔记]《清醒思考的艺术: 你最好让别人去犯的52种思维错误》

《清醒思考的艺术: 你最好让别人去犯的52种思维错误》


[笔记] 《编写可读代码的艺术》

《编写可读代码的艺术》


[设计模式] Adapter

Adapter


[设计模式] 工厂模式

工厂方法模式 与 抽象工厂模式