Effective Java 学习-创建和销毁对象

Effective Java 学习-创建和销毁对象

左岸 177 2022-12-14

创建和销毁对象

1. 用静态工厂方法代替构造器

  • 优势

    1. 具有合适的名称

    当一 类需要多个带有相同签名的构造器时,就用静态工厂方法代替构造器,并且仔细地选择名称以便突出静态工厂方法之间的区别

    1. 不必每次调用都创建新的对象
    2. 返回任何子类型的对象
    3. 所返回的对象的类可以随着每次调用而发生变化,取决于方法的参数
    4. 方法返回的对象所属的类,在编写包含该静态工厂方法的类时可以不存在

    这种灵活的静态工厂方法构成了服务提供者框架( Service Provider Framework )的基础,例如 JDBC(Java 数据库连接)API 服务提供者框架是指这样一个系统:多个服务提供者实现一个服务,系统为服务提供者的客户端提供多个实现,并把它们从多个实现中解稠出来

  • 缺点

    1. 类如果不含公有的或者受保护的构造器,就不能被子类化
    2. 程序员很难发现它们

    在API 文档中,它没有像构造器那样在 API 文档中明确标识出来,要想查明如何实例化一个类是非常困难的

2. 遇到多个构造器参数时要考虑使用构建器

静态工厂和构造器有个共同的局限性:它们都不能很好 扩展到大量的可选参数 比如用一个类表示包装食品外面显示的营养成分标签 这些标签中有几个域是必需的:每份的含量、每罐的含量以及每份的卡路里 还有超过 个的可选域 肪量、饱和脂肪量、转化脂肪、胆固醇、纳,等等 大多数产品在某几个可选域中都会有非零的值

简而言之 如果类的构造器或者静态工厂中具有多个参数,设计这种类时,Builde模式就是一种不错的选择, 特别是当大多数参数都是可选或者类型相同的时候 与使用重叠构造器模式相比,使用 Bui lder 模式 的客户端代码将更易于 阅读和编写,也更加安全

3. 用私有构造器或枚举类型强化Singleton 属性

Singleton 是指仅仅被 例化一次 Gamma95 Singleton 通常被用来代表一个无状态的对象

4. 通过私有构造器强化不可实例化的能力

有时候可能需要编写只包含静态方法额静态域的类,我们可以让这个类包含一个私有构造器,它就不能被实例化了,这样可以避免人们误用

这样的做法也有副作用,它使得一个不能被子类化

5. 优先考虑依赖注入来引入资源

总而言之,不要用 singleton 和静态工具类来实现依赖一个或多个底层资源的类,且该资源的行为会影响到该类的行为 ;也不要直接用这个类来创建这些资源 而应该将这些资源或者工厂传给构造器(或者静态工厂,或者构建器),通过它们来创建类这个实践就被称作依赖注入,它极大地提升了类的灵活性可重用性和可测试性

依赖注入极大地提升了灵活性和可测试性,但是它会导致大型项目凌乱不堪,因为它通常包含上千个依赖,不过这种凌乱可以用一个依赖注入框架解决

6. 避免创建不必要的对象

一般来说,最好能用单个对象,而不是在每次需要的时候就创建一个相同功能的新对象 重用方式既快速,又流行 如果对象是不可变的,它就始终可以被重用

7. 消除过期的对象引用

8.避免使用终结方法和清除方法

  1. 终结方法( finalize())通常是不可预测的,也是很危险的,一般情况下是不必要的
  2. 在 Java 9 中用清除方法( cleaner )代替了终结方法 清除方法没有终结方法那么危险,但仍然是不可预测、运行缓慢,一般情况下也是不必要的

9. try -with-resources 优先 try -finally

结论很明显 在处理必须关闭的资源时,始终要优先考虑用 try with resources ,而不是try-finally 这样得到的代码将更加简洁、清晰,产生的异常也更有价值 有了 trywith resources 语句,在使用必须关闭的资源时,就能更轻松地正确编写代码了 实践证明,这个用 try-finally 是不可能做到的