Java 中的单例模式和静态类之间的区别

2025年6月23日 | 阅读 5 分钟

在Java中,单例模式和静态类都用于控制实例创建和访问类级别行为,但它们的目的不同,特性也各不相同。

单例模式

Java中的单例模式是一种设计模式,它保证一个类只有一个实例,并提供对该实例的集中访问点。当应用程序的各个部分都应该只有一个类的实例时,就可以使用它。这种情况通常需要共享配置、日志对象或资源池,这些对象需要保持一致且可全局访问。

Difference Between Singleton Pattern and Static Class in Java

可以通过以下方式实现单例设计模式:

  • 隐藏构造函数:将单例类的所有构造函数声明为私有,以便外部类无法创建单例类的对象。私有构造函数不仅限制了实例化,还允许类本身控制实例化。
  • 使用getInstance()方法:该方法仅返回该类的一个实例。它将成为访问该类唯一实例的全局入口点。
  • 私有的静态变量,类型与您的单例类相同,它将存储该类的唯一实例。

单例模式可以同时拥有静态和实例成员,从而提高了实现的灵活性。其主要目标是提供对不应重复的资源的受控、线程安全的访问。

示例:单例设计模式

示例

编译并运行

输出

Singleton instance created
Hello from Singleton!
true

静态类

静态类是仅包含静态成员的类。所有类实例共享静态成员,子类无法重写它们。在Java中,只有嵌套(内部)类可以声明为静态;外部类不能是静态的。静态类是分组类的便捷方式。Java不允许创建顶层静态类;只允许创建嵌套(内部)类。这就是为什么静态类也称为静态内部类或静态嵌套类。

示例:静态类

示例

编译并运行

输出

Value of myVariable: 32
Value of myVariable: 32
It is the Inner Class Constructor
Value of myVariable from inside Inner Class: 32

单例模式与静态类之间的区别

特性单例模式静态类
定义确保类只有一个实例的设计模式。包含所有静态成员的类。
创建实例使用私有构造函数创建。静态成员在类首次加载时初始化。
访问实例通过静态方法访问。直接访问实例。
继承该类可以被继承。该类不能被继承。
多态该类可以被多态地使用。该类不能被多态地使用。
线程安全实例是线程安全的。实例不是线程安全的。
可测试性该类易于测试。该类难以测试。
内存使用它使用堆内存。它使用栈内存。
用作参数单例类可以用作方法参数。静态类不能用作方法参数。 
对象处置可以处置对象。无法处置静态类,因为没有创建实例。
垃圾回收器由于使用堆内存,它在垃圾回收器的范围内工作。由于使用栈内存,它不在垃圾回收器的范围内。
面向对象遵循面向对象原则。它通过缺少实例和继承来违反面向对象原则。
延迟初始化它可以支持延迟实例化。没有实例化概念。
内存消耗仅在创建实例时才使用内存。静态内存分配可能需要更多的预分配内存。
状态管理它可以维护每个实例的内部状态。它无法维护状态;只有静态数据。
灵活性更灵活;允许通过接口更改行为。不够灵活;行为硬编码。
序列化支持经过适当处理后,可以使其可序列化。不适用。
用例示例管理共享配置对象、日志记录和数据库访问。Math、Collections等工具/助手方法。

单例模式与静态类选择题

1. 关于单例模式,以下哪个陈述是正确的?

  1. 单例类不能被继承
  2. 单例类只允许创建一个类的实例
  3. 单例类只能包含静态方法
  4. 单例模式违反了面向对象原则
 

答案:b)

解释:单例模式确保在整个应用程序生命周期中只创建一个类的实例。它可以包含实例方法和静态方法。


2. 以下哪项不是Java中静态类的特征?

  1. 无法实例化
  2. 支持多态
  3. 所有成员都是静态的
  4. 不能扩展
 

答案:b)

解释:Java中的静态类不能被多态地使用,因为它们不能被实例化或继承。多态依赖于对象实例和继承。


3. 在Java中,通常如何访问单例实例?

  1. 使用new关键字
  2. 通过公共构造函数
  3. 通过静态getInstance()方法
  4. 直接通过类名访问
 

答案:c)

解释:单例类使用私有构造函数,并提供一个公共静态方法(getInstance())来返回该单例实例。


4. 关于Java中的静态类,以下哪个说法是正确的?

  1. 它们是延迟初始化的
  2. 它们紧密遵循OOP原则
  3. 它们只在需要时消耗内存
  4. 它们在首次引用类时加载
 

答案:d)

解释:静态类在首次被引用时由JVM加载,并在那时初始化其静态成员。


5. 哪些单例模式支持而静态类不支持的特性?

  1. 拥有静态方法
  2. 支持继承
  3. 通过类名访问
  4. 在类加载时初始化
 

答案:b)

解释:单例类是实际的对象,可以被扩展(尽管通常避免),而静态类隐式是final的,不能被扩展。