创建和销毁对象

本文是Java 四大教科书之一的Effective Java的中文第三版的笔记整理

第二章:创建和销毁对象

1,用静态方法类替代构造器

为什么要使用静态方法而不是public构造器:
优点:
1,静态方法是有名字的,构造器只能根据参数来决定返回实例的类型.但是通过静态工厂方法就可以避开这个过程.
2,可以复用对象,不用每次都创建一个新的实例,而这个实例可以是提前构造好的,从而实现实例受控类.
3,返回原返回类型的任何子类的对象.
4,返回对象的类可以随着每次调用而发生变化,取决于参数值.
5,方法返回的对象的所属类,在编写包含该静态工厂方法的类时可以不存在

缺点:
1,类如果不包含公有的或者protected的构造器,就不能被子类化.
2,程序员可能无法发现他们

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

因为静态工厂和构造器都有个共同的局限性,不能扩展到大量的可选参数.
一个替代的方法是用的javaBeans模式,先调用一个无参构造器来构造对象,然后使用setter方法来设置必要的参数.
但是这个办法也会有线程安全的问题,如果强行冻结的话就很笨拙.

实际生产过程中是用的建造者模式来处理,使用lombok的builder方法,先使得客户端利用所有必要的参数调用构造器,得到一个builder对象,再在builder对象上调用build方法来生成不可变的对象.
builder一般是它构建的类的静态成员类.
优点是流式编程,而且模拟了具名的可选参数.

一个大优点是便于扩展参数,对于之前的代码,可以保持原有的builder不变.

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

首先要注意私有方法还是可以被反射给调用,所以要在构造器中添加二次创建就报异常的机制.
有两种常见方法:
1.public静态成员,final域
创建和销毁对象

2,public获取方法,final成员
创建和销毁对象

方法2有3个好处:
1,便于修改,保持api不变.
2,简单,可以返回一个泛型Singleton工厂
3,可以通过方法引用来提供实例.

注意还要声明所有实例域都是transient的,并且提供一个readResolve方法.

3,声明一个包含单个元素的枚举类型
创建和销毁对象
这是最好的方法.

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

对于一些只包含静态方法的类,实例化是毫无意义的,但是如果不包含构造器,系统会提供一个默认的无参构造器.所以需要给一个私有的构造器,这样就可以完全避免被实例化了.
私有构造器可以直接抛出一个异常,以防在内部被错误调用.
这样的一个问题就是该类不可被子类化,因为无法调用超类的构造器.

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

比如使用spring这种方法,定义依赖并且把依赖注入,从而进行使用.

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

多使用静态工厂方法避免使用构造器
比如创建string的时候,避免调用构造器,而是直接赋值.
以及使用基本变量类型的时候,尽可能避免自动装箱.
或者使用正则表达式的时候,先显式定义再进行调用.

7.消除过期的对象引用

过期引用: 永远不会再被解除的引用
往往发生在自己管理内存的类上

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

能不用就不用.
记得每次使用完资源都close一下;

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

实际使用就是在try的括号里打开资源,并且不需要使用finally这个方法来关闭资源了,从而避免异常覆盖.

创建和销毁对象