创建和销毁对象

第1条:考虑用静态工厂方法代替构造函数
好处:
1。静态工厂方法的第一个好处是,与构造函数不同,静态方法具有名字
2.静态工厂方法的第二个好处是与构造函数不同,它们每次被调用的时候,不要求非得创建一个新的对象
3.静态工厂方法的第三个好处是与构造函数不同,它们可以返回一个原返回类型的子类型的对象。这样我们在选择返回对象的类型时就有了更大的灵活性。

缺点
1.静态工厂方法的主要缺点是,类如果不含有公有的或者受保护的构造函数,就不能被子类化。
2.静态工厂方法的第二个缺点是,它们与其他的静态方法没有任何区别。

第2条:使用私有构造函数强化singleton属性

第一种方法
public class Elvis{
public static final Elvis INSTANCE=new Elvis()
private Elvis(){}
}
第二中方法
ublic class Elvis{
private static final Elvis INSTANCE=new Elvis()
private Elvis(){}
public static Elvis getInstance(){
return INSTANCE;
}
}

第一种方法的主要好处在于组成员的类声明很清楚的表明了这个类是一个singleton:公有的静态域是final的。
第二中方法的主要好处在于,它提供了灵活性;在不改变api的前提下,允许我们改变想法,把该类做成singleton或者不做成singleton。比如说为每个方法的线程返回一个唯一的实例。

第3条:通过私有构造函数强化不可实例化的能力

只包含静态方法和静态域的类(比如工具类Collections),对它进行实例化没有任何意义。
企图通过将一个类做成抽象类来强制该类不可被实例化,这是行不通的。该类可以被子类化,并且该子类也可以被实例化。更一进一步,这样做会误导用户,以为这种类是专门为了继承而设计的。我们只要将这个类包含单个显示的私有构造函数,则它就不可被实例化。
这样习惯用法也有副作用,它使的一个类不能被子类化。所有的构造函数都必须调用一个可访问的超类构造函数,无论显示的或是隐士的,在这种情况下,子类就没有可访问的构造函数来调用了。

第4条:避免创建重复对象
重复使用同一个对象,而不是每次需要的时候就创建一个功能上等价的新对象。如果一个对象是非可变的,那么它总是可以被重用。

不要错误的认为本条目所介绍内容暗示:创建对象的代价是非常昂贵的,我们应该要尽可能得避免创建对象。相反,由于小对象的构造函数只要做少量的工作,所以小对象的创建和回收动作是非常廉价的。特别是在现代的jvm实现更是如此。通过创建附加对象以使得一个程序更加清晰,简洁,功能强大,这往往也是一件好事。
反之,通过维护自己的对象池来避免创建对象的创建工作并不是一个好的做法,除非池种的对象是非常重量级的。一个正确使用对象池的典型例子就是数据库连接。
然而一般而言,维护自己的对象池会把代码弄的很乱,增加内存占用,并且还损害性能,现代的jvm实现有高度优化的垃圾回收器,其性能很容易超过轻量级对象池的性能。

第5条:消除过期的对象引用

第6条:避免使用终结函数
终结函数(finalizer)通常是不可预测的,常常也是很危险的,一般情况下是不要的。使用终结函数会导致不稳定的行为,更差的性能,以及带来移植行问题。
终结函数并不能被及时的执行,从一个对象变的不可到达开始,到它的总结函数被执行,这段时间的长度是任意的,不确定的。这意味着,时间关键的任务不应该由终结函数来完成。
如果一个程序依赖于终结函数被执行的时间点,那么这个程序的行为在不同的jvm中运行的表现可能会截然不同。
不要被system.gc和system.runFinalization这两个方法所诱惑,它们确实能增加终结函数的执行机会,但是不保证终结函数一定会被执行。
那么,如果一个类封装的资源确实需要回收,我们应该怎么办?只需要提供一个显示的终止方法,并要求该类的客户在每个实例不在有用的时候调用这个方法。
一个值得提的细节是,该实例必须记录自己是否已经被终结了:显示的终止方法必须在一个私有域中记录下“该对象已经不在有效了”,其他方法必须检查这个域,如果在该对象已经被终止之后,这些方法调用的话,那么他们应该抛出illegalstateException。
显示终止方法的一个典型例子是InputStream的close方法。
显示的终止方法通常与try finally结合使用,以确保及时终止。

终结函数有什么好处呢?1,当一个对象的所有者忘记调用了显示终止方法的情况,终结函数可以充当安全网,虽然并不能保证被及时调用,InputStream有终结函数。2.普通对象通过本地方法委托给一个本地对象。因为本地对象不是一个普通对象,所以垃圾回收不会知道它,当它的普通对象被回收的时候,本地对象不会被回收,此时就可以派上用场。
终结函数连不会被自动执行,子类改写父类终结函数,那么子类终结函数必须手工调用超类的终结函数。
总之,除非是作为安全网,或者是为了终止非关键的本地资源,否则请不要使用终结函数,即是使用了那么记住调用super.finalize.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值