之前看这本《Effective Java(第二版)》都是很早以前了,这本书确实是本好书,需要细嚼慢咽,每次看都有不同的体验。在此写博客巩固一下。
第一章.创建和销毁对象
考虑用静态工厂方法代替构造器
通常我们获取类的实例,较为常用的方法是使用构造器,而这里要讲的是使用公有的静态工厂方法(注意:静态工厂方法和设计模式中的工厂方法模式是不同意思)
Map<String,List<String>> map= new HashMap<String,List<String>>();//这样的写法比较麻烦 <pre name="code" class="java">//假设HashMap 提供了这个静态工厂: public static <K,V> HashMap<K,V> newInstance(){ return new HashMap<K,V>(); } //那么我们就可以这么写,如下 Map<String,List<String>> map=HashMap.neweInstance();
遇到多个构造器参数时要考虑用构建器
静态工厂和构造器都有局限性,不能很好的扩展到大量的可选参数。通常我们习惯采用重叠的构造器
public A(int a,int b){ this.A(a,b,1); } public A(int a,int b,int c){ /////// }我们可以发现,重叠构造器是可行的,不过面对多个参数时,就会异常复杂了。那么我们就要用到JavaBeans模式了。
public int a=0; public int b=0; public int c=0; public A(){ public void seta(int a){ this.a=a; } public void setb(int b){ this.b=b; } public void setc(int c){ this.c=c } }这样就弥补了重叠构造器的复杂的不足。不过,JavaBeans本身也是有缺陷的,因为构造过程被分割到几个调用中,在构造过程中JavaBeans可能处于不一致的状态,类无法仅仅通过检验构造器参数的有效性来保持一致性。视图使用处于不一致状态的对象,将会导致失败。
用私有构造器或者枚举类型强化Singleton属性
singleton指仅仅被实例化一次的类,Singleton往往用来代表那些本质上唯一的系统组件。
通过私有构造器强化不可实例的能力
有时候我们需要编写只包含静态方法和静态域的类,常常我们需要用到java.lang.Math里的方法,其中的调用就是如此。
避免创建不必要的对象
通常最好能重用对象而不是在每次需要的时候就创建一个相同功能的新对象,对于同时提供了静态工厂方法和构造器的不可变类,通常可以使用静态工厂方法而不是构造器,以避免创建不必要的对象。通过维护对象池来避免创建对象并不是一种好的做法,除非池中的对象是非重量级的。真正正确使用对象池的典型是数据库链接池,建立数据库链接的代价输很昂贵的,所以重用这些对象就非常有必要了。
消除过期的对象引用
消除过期的引用最好的办法是让包含该引用的变量结束其生命周期,如果是在最紧凑的作用域范围内定义每一个变量,这种就会发生。一般来说,只要是自己管理内存的,我们就应当警惕内存泄漏问题,一旦元素被释放掉,则该元素中包含的任何对象引用都应该被清空。内存泄漏的一个常见来源缓存,一旦你把对象的引用放到缓存中,就很容易被遗忘掉。内存泄漏的另一个来源监听器和其他回调,如果你实现了一个API,客户端在这个API中注册回调,却没有显示地取消注册,那么除非你采取某些动作,否则就会累积,解决方案是只保存它们的弱引用。