创建和销毁对象_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 创建和销毁对象

创建和销毁对象

 2014/11/18 3:44:25  逆天子军少  程序员俱乐部  我要评论(0)
  • 摘要:本系列博客皆为读书笔记。读者可看原书<<EffectiveJava>>本篇的主题是创建和销毁对象。第一条:考虑用静态工厂方法代替构造器为了获取类的一个实例,最常用的方法就是提供一个公有的构造器,但类也可以提供一个公有的静态工厂方法。(这里的静态工厂方法与设计模式中的工厂方法模式不同)静态工厂方法与构造器相比有下面几个优势:1.静态工厂方法有名称具有适当名称的静态工厂将更容易使用和阅读。2
  • 标签:创建
系列博客皆为读书笔记。读者可看原书<<Effective Java>>

本篇的主题是创建和销毁对象

第一条:考虑用静态工厂方法代替构造器
为了获取类的一个实例,最常用的方法就是提供一个公有的构造器,但类也可以提供一个公有的静态工厂方法。(这里的静态工厂方法与设计模式中的工厂方法模式不同)
静态工厂方法与构造器相比有下面几个优势:
1.静态工厂方法有名称
具有适当名称的静态工厂将更容易使用和阅读。
2.不必在每次调用静态工厂方法的时候都创建一个新对象
这个优势使得不可变类可以使用预先构件好的实例,或者将构架好的实例缓存起来,进行重复利用,从而避免创建不必要的重复对象。
3.返回原返回类型的任何子类型的对象
我们在选择返回对象的类时有了很大的灵活性,其中一种应用是,API可以返回对象,同时又不会使对象的类变成共有的。以这种方式隐藏实现类会使API变得非常简洁。这项技术适用于基于接口的框架,在这种框架中,接口为静态工厂方法提供了自然返回类型。
4.在创建参数化类型实例的时候,静态工厂方法使代码变得更加简洁
class="java">Map<String , List<String>> m = HashMap.newInstance();

但是静态工厂方法也有缺点:
1.类如果不含公有的或者受保护的构造器,就不能被子类化
2.静态工厂方法与其他的静态方法实际上没有任何区别
不能像构造器那样明确标识,在提供了静态工厂方法而不是构造器的类中,要想查明如何实例化一个类,比较困难。但也还是有些惯用名称:valueof ,of , getInstance , newInstance , getType , newType.

第二条:遇到多个构造器参数时要考虑用Builder模式
静态工厂和构造器有个共同的局限性,都不能很好地扩展到大量的可选参数。可能你喜欢用重叠构造器模式,但参数很多时,代码很难编写,阅读性差。或者你喜欢用JavaBeans模式,这种模式确实弥补了构造器模式的不足,但其自身有着严重的缺点。因为构造过程中被分到了几个调用中,在构造过程中JavaBean可能处于不一致的状态。而且,JavaBeans模式阻止了把类做成不可变类的可能。
这时,我们有第三种方法,既能保证安全性也能保证可读性,那就是Builder模式。不直接生成想要的对象,而是让客户端利用所有必要的参数调用构造器(或静态工厂方法),得到一个builder对象。然后客户端在builder对象上调用类似setter方法,设置每个相关的可选参数。最后,客户端调用无参的build方法来生成不可变的对象。这个builder是它构建的类的静态成员类。

第三条:用私有构造器或者枚举类型强化Singleton属性
Singleton是指仅仅被实例化一次的类。在java 1.5发行之前,实现Singleton有两种方法。这两种方法都要把构造器保持为私有,并导出公有的静态成员。这个静态成员可以是final域或者是静态方法。从java 1.5发行起,实现Singleton还有第三种方法,只需编写一个包含单个元素的枚举类型:
public enum Elvis{
  INSTANCE;

 public void method(){...}
}

这种方法已经成为实现Singletong的最佳方法,更加简洁,并无偿提供了序列化机制,绝对防止多次实例化,即使是面对复杂的序列化或者反射攻击。

第四条:通过私有构造器强化不可实例化的能力
企图通过将类做成抽象类来强制该类不能被实例化,是行不通的。该类可以被子类化,该子类可以被实例化。我们可以让这个类包含私有构造器,她就不能被实例化了。但在这种情形下,子类就没有可访问的超类构造器可调用了。

第五条:避免创建不必要的对象
并不意味着创建对象的代价非常昂贵。相反,由于小对象的构造器只做很少量的显式工作,所以,小对象的创建和回收是非常廉价的。

第六条:消除过期的对象引用
java因为支持垃圾回收,所有有些情况下内存泄露是很隐蔽的。如果一个对象引用被无意识的保留起来了,那么,垃圾回收机制不仅不会处理这个对象,而且也不会处理被这个对象所引用的所有其他对象。
这类问题的修复方法很简单:一旦对象引用已经过期,只需清空这些引用即可。一般而言,只要类是自己管理内存(比如Stack),程序员就应该警惕内存泄露。一旦元素被释放掉,该元素中包含的任何对象就应该被清空。内存泄露的另一个常见来源是缓存。缓存应该时不时清除掉无用的项,这项清除工作可以由一个后台线程完成,或者也可以在给缓存添加新条目时顺便进行清理。LinkedHashMap可以很容易实现后一种方案。对于更加复杂的缓存,直接使用java.lang.ref。内存泄露的第三个来源是监听器和其他回调。确保回调立即被当做垃圾回收的最佳方法是只保存他们的弱引用。

第七条:避免使用终结方法
终结方法(finalizer)通常是不可预测的,也是很危险的。其缺点在于不能保证会被及时执行,甚至不能保证会不会执行。我们可以提供一个显示的终止方法代替编写终结方法。通常,终止方法与try-finally结合使用,确保及时终止。
终结方法有两种合法用途,充当“安全网”或者终止非关键的本地资源。即使使用了终结方法,也要记住调用super.finalize.如果用来充当安全网,要记得记录终结方法的非法用法。最后,如果需要把终结方法与公有的非final类关联起来,请考虑使用终结方法守卫者,确保即使子类的终结方法未能调用super.finalize,该终结方法也能被执行。


上一篇: VS2015中SharedProject与可移植类库(PCL)项目 下一篇: 没有下一篇了!
发表评论
用户名: 匿名