1. 要么设计继承并提供文档说明,要么禁止继承
    1. 必须有文档说明它可覆盖( overridable )的方法的自用性( self-use )
    2. 对于为了继承而设计的类,唯一的测试方法就是编写子类
    3. 必须在发布类之前先编写子类对类进行测试
    4. 构造器决不能调用可被覆盖的方法(clone/Cloneable和readObject/Serializable同样适用)
  2. 接口由于抽象类
    1. 现有的类可以很容易被更新,以实现新的接口
    2. 接口是定义 mixin (混合类型)的理想选择
    3. 接口允许构造非层次结构的类型框架
    4. 接口使得安全地增强类的功能成为可能
    5. 骨架实现类,定义接口,抽象实现
  3. 为后代设计接口
    1. 在 Java 8 中,增加了缺省方法( default method)构造[ JLS 9.4 ],目的就是允许给现有的接口添加方法
    2. 有了缺省方法,接口的现有实现就不会出现编译时没有报错或警告,运行时却失败的情况
  4. 接口只用于定义类型
    1. 常量接口模式是对接口的不良使用
    2. 如果这些常量最好被看作枚举类型的成员,就应该用枚举类型(enum type ) (详见第 34 条)来导出这些常量.否则,应该使用不可实例化的工具类( utility class )
  5. 类层次优于标签类
    1. 标签类过于冗长、容易出错,并且效率低下
    2. 为标签类中的每个方法都定义一个包含抽象方法的抽象类,标签类的行为依赖于标签值
  6. 静态成员类优于非静态成员类
    1. 嵌套类有四种: 静态成员类( static m巳mber class)、非静态成员类( nonstatic memb巳r class)、匿名类( anonymous class)和局部类( local class )
    2. 当非静态成员类的实例被创建的时候,它和外围实例之间的关联关系也随之被建立起来;而且,这种关联关系以后不能被修改, 需要消耗非静态成员类实例的空间,并且会增加构造的时间开销
    3. 如果声明成员类不要求访问外围实例,就要始终把修饰符 static 放在它的声明中(否则可能导致内存泄漏)
      1. 如果一个嵌套类需要在单个方法之外仍然是可见的,或者它太长了,不适合放在方法内部,就应该使用成员类 。
      2. 如果成员类的每个实例都需要一个指向其外围实例的引用,就要把成员类做成非静态的;否则,就做成静态的
      3. 假设这个嵌套类属于一个方法的内部,如果你只需要在一个地方创建实例, 并且已经有了一个预置的类型可以说明这个类的特征,就要把它做成匿名类;否则,就做成局部类
  7. 限制源文件为单个顶级类
    1. 永远不要把多个顶级类或者接口放在一个源文件中,遵循这个规则可以确保编译时一个类不会有多个定义
  8. 请不要使用原生类型
    1. 声明中具有一个或者多个类型参数( type parameter)的类或者接口,就是泛型( generic)类或者接口 [ JLS, 8.1.2, 9.1.2 ]
    2. 如果使用原生态类型,就失掉了泛型在安全性和描述性方面的所有优势
    3. 如果使用像 List 这样的原生态类型,就会失掉类型安全性 , 但是如果使用像 List<Object>这样的参数化类型,则不会
    4. 必须在类文字( class literal) 中使用原生态类型
    5. 来使用 instanceof确认类型,转换成通配符类型,而不是原生态类型,不受泛型约束
  9. 消除非受检的警告
    1. 要尽可能地消除每一个非受检警告
    2. 应该始终在尽可能小的范围内使用 SuppressWarnings 注解。@SuppressWarnings(“unchecked”)
    3. 每当使用 SuppressWarnings ( “ unchecked ” )注解时,都要添加一条注释,说明为什么这么做是安全的
  10. 列表优于数组
    1. 利用数组,你会在运行时才发现所犯的错误;而利用列表,则可以在编译时就发现错误
    2. 当你得到泛型数组创建错误时,最好的解决办法通常是优先使用集合类型 List<E>,而不是数组类型E[],这样可能会损失一些性能或者简洁性,但是换回的却是更高的类型安全性和互用性 。
  11. 优先考虑泛型
    1. 使用泛型比使用需要在客户端代码中进行转换的类型来得更加安全,也更加容易
    2. 在设计新类型的时候,要确保它们不需要这种转换就可以使用
  12. 优先考虑泛型方法
    1. 泛型方法就像泛型一样,使用起来比要求客户端转换输入参数并返回值的方法来得更加安全,也更加容易
    2. 确保方法不用转换就能使用,这通常意味着要将它们泛型化
  13. 利用有限制通配符来提升 API 的灵活性
    1. public void pushAll(Iterable<? e xtends E> src〕
    2. 为了获得最大限度的灵活性,要在表示生产者或者消费者的输入参数上使用通配符类型
    3. PECS 表示 producer-extends, consumer-super
    4. 不要用通配符类型作为返回类型
    5. 编写的是将被广泛使用的类库, 则一定要适当地利用通配符类型
    6. 基本的原则: producer-extends,consumer-super (PECS)
  14. 谨慎并用泛型和可变参数
    1. 当一个参数化类型的变量指向一个不是该类型的对象时,会产生堆污染
    2. 值保存在泛型可变参数数组参数中是不安全的
    3. SafeVarargs 注解是通过方法的设计者做出承诺,声明这是类型安全的
    4. 允许另一个方法访问一个泛型可变参数数组是不安全的
  15. 优先考虑类型安全的异构容器
    1. 泛型的一般用法, 限制每个容器只能有固定数目的类型参数
    2. 对于这种类型安全的异构容器,可以用 Class 对象作为键. 以这种方式使用的 Class 对象称作类型令牌