什么时候我们应该在Java中使用Singleton类?
根据我的想法,当我们在整个应用程序中共享相同的对象状态时,我们应该将类创建为Singleton。 在这种情况下,我们希望用户每次都限制创建一个新实例,以便它们不能维持多个状态。 同意。 但是通过将实例变量声明为静态可以实现相同的行为。 对我cacheobjectcontainer
,无论是cacheobjectcontainer
, logger
还是cacheobjectcontainer
Classloader
,它看起来也会起到同样的作用。
请帮助我理解上面的概念静态实例变量无法解决的目的和类需要声明Singleton?
编辑部分
好的,让我更清晰一些。 单例类的目的是在jvm中只保留一个单例类的实例。 同意。 但我试图想出为什么我们只想保留一个实例的原因。 原因有两个:
1)创建对象可能很昂贵。 所以我们只想保留一个实例。 在这种情况下同意将实例变量声明为静态并不能解决任何问题。
2)我们希望跨应用程序共享相同的对象状态。 我认为这是将类声明为单例的主要目的。 但只需将实例变量声明为静态即可实现。
但看起来像1是将任何类声明为静态而不是原因2的主要原因,因为它也可以用静态变量实现。
它是否正确?
声明实例变量使该引用成为静态对象。 这意味着该类只有一个实例。 但它不会阻止任何其他人做new SomeObject()
无论它是否是静态引用。 拥有单例类的想法是控制实例。 例如,如果您将构造函数设为private
,则无法执行new
来创建新实例。 因此,您正在控制实例的创建。
主要区别在于单例是一个普通实例,您可以将其用作参数。 单身人士也可以实现接口。
马特奥
到目前为止几个好的答案。
这是什么时候,Singleton不是Singleton的文章很好地表达了这个概念。
以下是一些额外的差异:
- 单身人士可以是有状态的,但静态变量却不能。
- 单例类可以是子类
如果您认为可能想要利用inheritance或接口,那么您将需要使用实际实例而不是静态类。 例如,如果您想将实例设置为执行与通常稍微不同的操作,该怎么办? 您可以将singleton值设置为接口的不同实现的实例,或者设置为覆盖某些function的子类。 访问该单例实例的所有代码都可以以完全相同的方式使用它,但其行为可以更改。
不过,我想补充一点,单身人士和静态课程现在被认为是一种反模式。 最好使用dependency injection,如果你想要单例行为,只需使用单例绑定。
public class SessionManager { private static final SessionManager instance; static { instance = SystemConfig.isDebug() ? new DebugSessionManager() : new SessionManager(); } public static SessionManager getInstance() { return instance; } public int getActivePersonId() { // default implementation } } public class DebugSessionManager : SessionManager { @Override public int getActivePersonId() { // debug implementation } } // The code can be used in the same way regardless of whether we're in debug mode: int personId = SessionManager.getInstance().getActivePersonId();
更新
在再次阅读问题后,听起来你正在考虑做这样的事情:
public class SessionManager { private static String systemName; public String getSystemName() {return systemName;} }
…假设systemName
永远不会改变,因此它是否作为new SessionManager().getSystemName()
与SessionManager.getInstance().getSystemName()
访问并不重要。 在这种情况下:
- 从语义的角度来看,当另一个程序员看到
new SessionManager()
,他们期望创建一些new
东西。 系统中的每个SessionManager
始终生成相同的systemName
并不是很明显。 因此,单身人士可能更为优选,只是为了让消费者更明显他们将处理单身国家。 - 创建
new SessionManager()
时会产生非常小的开销,以后必须进行垃圾回收。
除此之外,这种方法基本上具有相同的优点和缺点,就像使用Singleton一样。 不过,我会重申我先前的陈述:单身人士是一种反模式。 喜欢dependency injection。