创建和销毁对象
第1条:用静态工厂方法代替构造器
第2条:遇到多个构造器参数时要考虑使用构建器
建造者模式
第3条:用私有构造器或者枚举类型强化 Singleton 属性
三种实现单例的方法,注意防止使用反射,可以修改构造器,让它在被要求创建第二个实例的时候抛出异常。
最佳方式是枚举实现。
第4条:通过私有构造器强化不可实例化的能力
第5条:优先考虑依赖注入来引用资源
不要用 Singleton 和静态工具类来实现依赖一个或多个底层资源的类,且该资源的行为会影响到该类的行为 ;也不要直接用这个类来创建这些资源 而应该将这些资源或者工厂传给构造器(或者静态工厂,或者构建器),通过它们来创建类 这个实践就被称作依赖注入,它极大地提升了类的灵活性、可重用性和可测试性。
第6条:避免创建不必要的对象
例子:Map接口的keySet方法、自动拆装箱
第7条:消除过期的对象引用
例子:栈实现(栈自己管理内存)、缓存、监听器和其他回调
第8条:避免使用终结方法和清楚方法
缺点:1.不能保证被及时执行,而且根本就不能保证会被执行。
因为是由JVM管理的,优先级比较低。JVM平台不同,实现可能不同。注重时间的任务不应该由终结方法或清除方法来完成。永远不应该依赖终结方法或者清除方法来更新重要的持久状态。
2.如果忽略终结过程中被抛出来的未被捕获的异常,该对象的终结过程也会被终止。如果异常发生在终结方法中,终结过程会被中止,但当前线程不会受影响,甚至连警告都不会打印出来 。清除方法则没有这个问题,因为使用清除方法的一个类库控制它的线程。
3.非常严重的性能损失
4.严重的安全问题:它们为终结方法攻击打开了类的大门。
总而言之,除非是作为安全网,或者是为了终止非关键的本地资源,否 请不要使用
清除方法,对于在 Jav 之前的发行版本,则尽量不要使用终结方法 使用了终结方法
或者清除方法,则要注意它的不确定性和性能后果
第9条:try-with-resources优先于try-finally
对所有对象都通用的方法
第10条:覆盖equals方法时请遵守通用约定
覆盖的equals方法需要符合:自反性,对称性,传递性,一致性
复合优于继承。可用注解,或者IDE的自动生成,自己手写容易出错。
第11条:覆盖equals时总需要覆盖hashCode
在每个 盖了 equals 方法的类中, 必须 hashCode 方法.
相等的对象必须具有相等的散到码
一个好的散列函数通常倾向于“为不相等的对象产生不相等的散列码”
手工写hashcode,参考公式:result = 31 * result + c;
也可以用 Object.hash(…)传入必须的参数,获得hashcode
可以考虑将不可变的,计算散列值开销比较大的类的散列值缓存起来,使用构造器加载或者懒加载。
第12条:始终要覆盖toString方法
第13条:谨慎地覆盖clone
第20条:接口优于抽象类
Java只允许单继承,所以用抽象类作为类型定义受到了限制。
骨架实现类(抽象类) 模板方法模式
最小实现类(普通类)
总而言之,接口通常是定义允许多个实现的类型的最佳途径。如果你导出了一个重要的接口,就应该坚决考虑同时提供骨架实现类。而且,还应该尽可能地通过缺省方法在接口中提供骨架实现,以便接口的所有实现类都能使用。也就是说,对于接口的限制,通常也限制了骨架实现会采用的抽象类的形式。