实现单例的三种方法
A.公有域方法
public class Sigleton{
public static final Sigleton SIGLETON = new Sigleton();
private Sigleton(){
}
public void loadTheBuilding(){}
/**
* 为了维护并保证Singleton,必须声明所有实例域都是瞬时( transient )的,并提供一个 readResolve 方法。
* 否则,每次反序列化一个序列化的实例时,都会创建一个新的实例,比如说,在我们的例子中,会导致“假冒的Elvis”
* @return
*/
private Object readResolve(){
return SIGLETONMODELSTATICFACTORY;
}
}
该方法好处在于:组成类的成员的声明很清楚地表明了这个类是一个Singleton:公有的静态域是 final 的,所以该域总是包含相同的对象引用。公有域方法在性能上不再有任何优势:现代的JVM(Java虚拟机,Java Virtual Machine)实现几乎都能够将静态工厂方法的调用内联化。
B.静态工厂方法
public class Sigleton{
private static final Sigleton SIGLETON = new Sigleton();
private Sigleton(){}
public static Sigleton(){
return SIGLETON;
}
public void loadTheBuilding(){}
/**
* 为了维护并保证Singleton,必须声明所有实例域都是瞬时( transient )的,并提供一个 readResolve 方法。
* 否则,每次反序列化一个序列化的实例时,都会创建一个新的实例,比如说,在我们的例子中,会导致“假冒的Elvis”
* @return
*/
private Object readResolve(){
return SIGLETONMODELSTATICFACTORY;
}
}
在不改变其API的前提下,我们可以改变该类是否应该为Singleton的想法。
值得注意的是:A、B两种方法,在享有特权的客户端可以借助 AccessibleObject.setAccessible 方法,通过反射机制调用私有构造器。如果需要抵御这种攻击,可以修改构造器,让它在被要求创建第二个实例的时候创建异常。
C..枚举实现
public enum Sigleton{
SIGLETON;
public void leaveTheBuilding(){}
}
该方法适用于JDK1.5版本及以上,单元素的枚举类型已经成为实现Singleton的最佳方法。