📜  Java中的Singleton/单例类

📅  最后修改于: 2020-04-02 14:40:53             🧑  作者: Mango

在面向对象的编程中,单例类是一次只能有一个对象(该类的实例)的类。
第一次之后,如果我们尝试实例化Singleton类,则新变量还将指向创建的第一个实例。因此,无论我们通过任何实例对类中的任何变量进行任何修改,它都会影响所创建的单个实例的变量,并且如果我们通过定义的该类类型的任何变量访问该变量,则该变量可见。
设计单例类:

  1. 将构造函数设为私有。
  2. 编写具有此单例类的返回类型对象的静态方法。在这里,使用惰性初始化的概念来编写此静态方法。

普通类与Singleton类:在实例化方面,普通类和Singleton类的区别在于,对于普通类,我们使用构造函数,而对于Singleton类,我们使用getInstance()方法(示例代码:I)。通常为避免混淆,我们在定义此方法时也可以使用类名作为方法名(示例代码:II)。

使用getInstance()方法实现Singleton类

// Jav程序,实现Singleton类
// getInstance()方法
class Singleton
{
    // 静态变量single_instance
    private static Singleton single_instance = null;
    // String类型变量
    public String s;
    // 私有构造函数
    private Singleton()
    {
        s = "Singleton的string";
    }
    // 静态方法,创造Singleton的对象
    public static Singleton getInstance()
    {
        if (single_instance == null)
            single_instance = new Singleton();
        return single_instance;
    }
}
// 测试代码
class Main
{
    public static void main(String args[])
    {
        // 初始化Singleton的x
        Singleton x = Singleton.getInstance();
        // 初始化Singleton的y
        Singleton y = Singleton.getInstance();
        // 初始化Singleton的z
        Singleton z = Singleton.getInstance();
        // 改变x
        x.s = (x.s).toUpperCase();
        System.out.println("String 来自 x 是 " + x.s);
        System.out.println("String 来自 y 是 " + y.s);
        System.out.println("String 来自 z 是 " + z.s);
        System.out.println("\n");
        // 改变z
        z.s = (z.s).toLowerCase();
        System.out.println("String 来自 x 是 " + x.s);
        System.out.println("String 来自 y 是 " + y.s);
        System.out.println("String 来自 z 是 " + z.s);
    }
}

输出:

String 来自 x 是  SINGLETON的STRING
String 来自 y 是 SINGLETON的STRING
String 来自 z 是 SINGLETON的STRING singleton的string
String 来自 x 是  singleton的string
String 来自 y 是  singleton的string
String 来自 z 是 singleton的string

说明:在Singleton类中,当我们第一次调用getInstance()方法时,它将创建一个名为single_instance的类的对象,并将其返回给变量。由于single_instance是静态的,因此将其从null更改为某个对象。下次,如果我们尝试调用getInstance()方法,由于single_instance不为null,则将其返回到变量,而不是再次实例化Singleton类,这部分由if条件完成。

在主类中,我们通过调用静态方法getInstance()来实例化具有3个对象x,y,z的单例类。但是实际上在创建对象x之后,变量y和z指向对象x,如图所示。因此,如果我们更改对象x的变量,这将在访问对象y和z的变量时反映出来。同样,如果我们更改对象z的变量,这将在访问对象x和y的变量时反映出来。

 

用方法名作为类名实现Singleton类

 

// Java实现Singleton类
class Singleton
{
    // 静态变量single_instance
    private static Singleton single_instance=null;
    // String类型变量
    public String s;
    // 私有构造函数
    private Singleton()
    {
        s = "Singleton的string";
    }
    // 静态方法,创造Singleton的对象
    public static Singleton Singleton()
    {
        // 只有一个对象被创建
        if (single_instance == null)
        {
            single_instance = new Singleton();
        }
        return single_instance;
    }
}
// 测试代码
class Main
{
    public static void main(String args[])
    {
        // 初始化Singleton的x
        Singleton x = Singleton.Singleton();
        // 初始化Singleton的 y
        Singleton y = Singleton.Singleton();
        // 初始化Singleton的 z
        Singleton z = Singleton.Singleton();
        // 改变x
        x.s = (x.s).toUpperCase();
        System.out.println("String 来自 x 是 " + x.s);
        System.out.println("String 来自 y 是 " + y.s);
        System.out.println("String 来自 z 是 " + z.s);
        System.out.println("\n");
        // 改变x
        z.s = (z.s).toLowerCase();
        System.out.println("String 来自 x 是 " + x.s);
        System.out.println("String 来自 y 是 " + y.s);
        System.out.println("String 来自 z 是 " + z.s);
    }
}

输出:

String 来自 x 是 SINGLETON的STRING
String 来自 y 是 SINGLETON的STRING
String 来自 z 是 SINGLETON的STRING
String 来自 x 是 singleton的string
String 来自 y 是 singleton的string
String 来自 z 是 singleton的string

说明:在Singleton类中,当我们第一次调用Singleton()方法时,它将创建一个名称为single_instance的Singleton类的对象,并将其返回给变量。由于single_instance是静态的,因此将其从null更改为某个对象。下次如果我们尝试调用Singleton()方法,则由于single_instance不为null,它将返回到变量,而不是再次实例化Singleton类。