单例模式(Singleton)

本文介绍了单例模式的概念及其三种实现方式:饿汉式、懒汉式和登记式单例类。详细解释了每种实现的特点,并提供了具体的Java代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作为对象的创建模式,单例模式确保某哦一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。

单例模式结构

很显然单例模式的要点有三个:

  • 单例类只能有一个实例。
  • 单例类必须自己创建自己的唯一实例。
  • 单例类必须给所有其它对象提供这个实例。

饿汉式单例类

饿汉式单例类是在Java语言里实现起来最为简便的单例类,下图所示的类图描述了一个饿汉式单例类的典型实现:
这里写图片描述

public class EagerSingleton {
    private static final EagerSingleton m_instance = new EagerSingleton();

    /**
     * 私有默认构造方法
     */
    private EagerSingleton() { }

    /**
     * 静态工厂方法
     */
    public static EagerSingleton getInstance() {
        return m_instance;
    }
}

懒汉式单例类

与饿汉式单例类相同之处是,类的构造方法是私有的。与饿汉式单例类不同的是,懒汉式单例类在第一次被引用时将自己实例化。如果加载器是静态的,那么懒汉式单例类被加载时是不会将自己实例化的。如下图所示,类图中给出了一个典型的懒汉式单例类的实现。
这里写图片描述

public class LazySingleton {
    private static LazySingleton m_instance = null;

    /**
     * 私有默认构造方法
     */
    private LazySingleton() {}

    /**
     * 静态工厂方法,返回此类唯一实例
     */
    public synchronized static LazySingleton getInstance() {
        if(m_instance == null) {
            m_instance = new LazySingleton();
        }
        return m_instance;
    }
}

登记式单例类

登记式单例类是为了克服饿汉式单例类及懒汉式单例类均不可继承的缺点而设计的。它的实例化方式是饿汉式,它的子类实例化方式只能是懒汉式的,这是无法改变的。如下图所示,是登记式单例类的一个例子,图中关系线表明此类已将自己实例化。
这里写图片描述

public class RegSingleton {
    private static HashMap m_registry = new HashMap();
    static {
        RegSingleton x = new RegSingleton();
        m_registry.put(x.getClass().getName(), x);
    }

    /**
     * 保护的默认构造方法
     * /
    protected RegSingleton(){}

    /**
     * 静态工厂方法,返回此类唯一实例
     */
    public static RegSingleton getInstance(String name) {
        if(name == null) {
            name = "com.javapatterns.singleton.demos.RegSingleton";
        }
        if(m_registry.get(name)==null) {
            try {
                m_registry.put(name, Class.forName(name).newInstance());
            } catch(Exception e) {
                System.out.println("Error happend");
            }
        }
        return (RegSingleton)(m_registry.get(name));
    }
    /**
     * 一个示例性的商业方法
     */
    public String about() {
        return "Hello I am RegSingleton";
    }
}

它的子类RegSingletonChild需要父类的帮助才能实例化。下图所示是登记式单例类子类的一个例子,图中的关系表明此类是由父类将子类实例化的:
这里写图片描述

public class RegSingletonChild extends RegSingleton {
    public RegSingletonChild() {}

    /**
     * 静态工厂方法,返回此类唯一实例
     */
    public static RegSingletonChild getInstance() {
        return (RegSingletonChild)RegSingleton.getInstance("com.javapatterns.demos.RegSingletonChild");
    }

    /**
     * 一个示例性的商业方法
     */
    public String about() {
        return "Hello I am RegSingletonChild";
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值