Singleton Class in Java

2025 年 3 月 28 日 | 阅读 4 分钟

在面向对象编程中,类是创建对象的蓝图或模板。从类创建的每个对象都有自己的一组属性(数据)和方法(函数),这些属性和方法定义了它的行为。在某些情况下,我们可能只希望在一个程序的整个生命周期中只有一个类的实例存在。这时就需要用到单例模式。在本文中,我们将讨论 Java 中的单例模式,并提供一些示例程序来说明其用法。

什么是单例类?

单例类是只允许创建自身一个实例的类,并提供该实例的全局访问点。这是通过将构造函数设为私有来实现的,这样就无法创建该类的其他实例,并提供一个静态方法来返回该类的唯一实例。

单例模式通常用于需要在系统中协调操作的场景,例如日志或配置系统。它确保只有一个类的实例,该实例可以全局访问,从而防止不必要的重复并确保整个系统的一致性。

在 Java 中实现单例类

  1. 声明一个私有静态变量来保存类的唯一实例。
  2. 将类的构造函数设为私有,这样就无法创建其他实例。
  3. 提供一个公共静态方法来返回类的唯一实例,并在需要时创建它。

示例 1: 饿汉式初始化的单例类

在此示例中,我们将使用饿汉式初始化来创建单例类的唯一实例。这意味着在类加载时创建实例,而不是在第一次访问时创建。

在此示例中,我们声明了一个名为 instance 的私有静态变量来保存类的唯一实例。我们将类的构造函数设为私有,这样就无法创建其他实例,并且我们提供了一个名为 getInstance 的公共静态方法来返回类的唯一实例。getInstance 方法仅返回 instance 变量。

让我们看看如何在一个程序中使用这个单例类。

SingletonDemo.java

输出

Both objects are the same instance.

在此示例中,我们使用 getInstance 方法创建了单例类的两个实例。由于 instance 变量是静态的并在类加载时初始化,因此两个实例将是同一个对象。我们使用 if 语句来检查这两个实例是否是同一个对象,并在控制台打印一条消息表示它们是。

示例 2: 懒汉式初始化的单例类

在上一个示例中,我们使用了饿汉式初始化来创建单例类的唯一实例。如果单例类是轻量级的并且没有其他类的依赖,这种方法效果很好。但是,如果单例类是重量级的或有依赖关系,饿汉式初始化可能不是最佳方法。

在此示例中,我们将使用懒汉式初始化来创建单例类的唯一实例。这意味着在第一次访问时创建实例,而不是在类加载时创建。

在此示例中,我们声明了一个名为 `instance` 的私有静态变量来保存类的唯一实例。与上一个示例不同,我们在声明时未初始化此变量。相反,我们在 `getInstance` 方法中使用懒汉式初始化,在首次访问时创建实例。

对 `getInstance` 方法进行了同步,以防止多个线程创建单例类的多个实例。我们检查 `instance` 变量是否为 null,如果是,则创建一个新的单例类实例。如果 `instance` 变量不为 null,我们仅返回现有实例。

让我们看看如何在一个程序中使用这个单例类。

SingletonDemo.java

输出

Both objects are the same instance.

在此示例中,我们使用 `getInstance` 方法创建了单例类的两个实例。第一次调用 `getInstance` 方法时,将创建实例。第二次调用该方法时,将返回现有实例。我们使用 if 语句来检查这两个实例是否是同一个对象,并在控制台打印一条消息表示它们是。

在本节中,我们讨论了 Java 中的单例模式,并提供了一些示例程序来说明其用法。我们看到了如何使用饿汉式和懒汉式初始化来实现单例类,以及如何在一个程序中使用单例类。单例模式是一种有用的设计模式,可以帮助确保系统的一致性并防止不必要的重复。