实现单例的三种方法

实现单例的三种方法

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的最佳方法。


猜你喜欢

转载自blog.csdn.net/h985161183/article/details/80749384
今日推荐