考虑用静态工厂方法代替构造函数
使用静态工厂方法的好处:
- 静态工厂有名字,多个构造函数只能通过参数列表来区分,编写起来可能会比较麻烦(比如有相同参数列表),使用起来也容易混淆,但静态工厂方法通过名字就可以很容易地被区分;
- 静态工厂方法不必每次调用时都新建一个对象。
- 静态工厂方法只需返回一个对象,对于使用者是透明的,即使用者不用考虑内部怎么实现,以后修改起来也很方便。
但是静态工厂方法和一般的静态方法没有任何区别,不会被明确标示出来,因此这些方法往往会起固定一点的名字,比如valueOf,getInstance。
使用私有构造函数强化singleton属性
将构造函数私有化,就只能在类内创建对象,要实现单例模式,只需在Class中创建一个对象,并将其用static修饰,标识为静态对象,其他类就可以通过访问此对象来调用此类的方法。一般有两种方式。
第一种:将唯一对象作为公共静态成员
public class Foo{
public static final Foo foo = new Foo();
private Foo(){....}
}
第二种:提供一个公有的静态工厂方法
public class Foo{
private static final Foo foo = new Foo();
private Foo(){....}
public static Foo getInstance(){ return foo;}
}
粗看之下两种方法都差不多,但如对象不能直接返回,需要多加一些操作时,第二种方法更好一些,除非你能保证这个对象以后永远不需要被修改,否则我还是建议用第二种更好一些。
通过私有构造函数强化不可实例化的能力
如果不写构造方法,类中是有一个默认用public修饰的构造方法的,写上构造方法后,原来默认的构造方法就不会被采用,因此写一个private构造方法,只能在本类中实例化对象。
避免创建重复的对象
一个极端的反面例子:
String s = new String("silly");
因为"silly"已经是一个String对象了,这条语句执行时又会new一个新的String对象,改进后的版本是:
String s = "silly";
这个版本只有一个String实例。避免重复创建对象的解决方法如下:
- 对于已经提供了静态工厂方法的类,通常可以使用静态方法而不是构造函数;
- 对于不可变类,建议只初始化一次,比如将创建实例的代码用static块包裹住;
消除过期的对象引用
作为Java程序员,不能理所当然地想着,自己不用考虑内存管理的事情,事实上还是有可能造成内存泄漏的,比如下面这段实现栈的代码:
这个程序没有太大的问题,它也可以通过每项测试,但其实它有一个“内存泄漏”的问题,如果一个栈先增长再收缩,那么,从栈中弹出来的对象将不会被当成垃圾回收,这是因为,栈内还维护着对这些对象的过期引用。
因此修复这一类问题也很简单,一旦对象引用过期,只需清空这些应用即可,一个修订版本如下:
避免使用终结函数
这部分主要解释了C++的析构函数和java中的终结函数是不一样的,由于不了解C++,就不乱说了,需要注意的是,内存垃圾并不会立即被GC回收,可能在内存不足的情况下才会触发GC,至于java的终结函数finalize,调用以后也不会马上被回收,而只是增加了它会被回收的概率。