单元素的枚举类型已经成为实现Singleton的最佳方法

转载请注明出处
http://blog.csdn.net/guodongAndroid/article/details/52032750
本文来自【孫小逗的博客】

一、概述

Singleton模式是在编程实践中应用最广泛的几种设计模式之一。以前常用的是下面的这种方法:

public class Singleton
{
    private volatile static Singleton instance;

    private Singleton(){};

    public static Singleton getInstance()
    {
        if (instance == null)
        {
            synchronized (Singleton.class)
            {
                if (instance == null)
                {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

这种方法称为双重校验锁,极不推荐使用。

二、其他实现Singleton的方法

1、饿汉式:
public class Singleton
{
    public static final Singleton INSTANCE = new Singleton();
    private Singleton(){};
}
2、饿汉式变种(1)
public class Singleton
{
    private static final Singleton INSTANCE = new Singleton();
    private Singleton(){};
    public static Singleton getInstance()
    {
        return INSTANCE;
    }
}

这两种方式都要求使用私有构造器,私有构造器仅被调用一次,用来实例化静态final域Singleton.INSTANCE。

3、饿汉式变种(2) 类初始化的时候实例化instance
public class Singleton
{
    private static Singleton instance = null;
    private Singleton(){};
    static
    {
        instance = new Singleton();
    }

    public static Singleton getInstance()
    {
        return instance;
    }
}
4、静态内部类
public class Singleton
{
    private static class SingletonHolder
    {
        private static final Singleton instance = new Singleton();
    }
    private Singleton(){};

    public static Singleton getInstance()
    {
        return SingletonHolder.instance;
    }
}

这四种方法都可以借助AccessibleObject.setAccessible方法,通过反射机制,调用私有构造器创建新的实例,如下图:
这里写图片描述

可见s1 == s2为fasle,说明创建了两个实例,也用失去了Singleton属性。如果需要抵御这种攻击,可以修改构造器,让它在被要求创建第二个实例的时候抛出异常。

三、使用单元素的枚举实现Singleton

public enum Singleton
{
    INSTANCE;

    public void dosomething()
    {
        System.out.println(this + " is speaking!");
    }
}

先看下运行后的结果:
这里写图片描述

这里写图片描述

使用单元素的枚举类型实现Singleton时,通过反射机制去创建新的实例时会抛出异常。

和以前的s1 == s2对比,可以看到使用单元素的枚举类型在功能上与公有域方法相近,但是它更加简洁,并且无偿得提供了序列化机制,绝对防止多次实例化。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值