根据我的想法,当我们在整个应用程序中共享相同的对象状态时,我们应该将类创建为Singleton。在这种情况下,我们希望用户每次都限制创建新实例,以便它们不能维持多个状态。同意。但是通过将实例变量声明为静态可以实现相同的行为。对我来说,无论是cacheobjectcontainer
,logger
还是Classloader
类,它看起来也会起到同样的作用。
请帮助我理解上面的概念静态实例变量无法解决的目的,并且需要将类声明为Singleton?
已编辑的部分
好的,让我更清晰一些。单例类的目的是在jvm中只保留一个单例类的实例。同意。但我试图想出为什么我们只想保留一个实例的原因。 原因有两个:
1)创建对象可能很昂贵。所以我们只想保留一个实例。在这种情况下同意将实例变量声明为静态并不能解决任何问题。
2)我们希望跨应用程序共享相同的对象状态。我认为这是将类声明为单例的主要目的。但它可以通过将实例变量声明为静态来实现。
但看起来像1是将任何类声明为静态而不是原因2的主要原因,因为它也可以用静态变量实现。
这是正确的吗?
答案 0 :(得分:7)
声明实例变量使该引用成为静态对象。这意味着 类只有一个实例。但它不会阻止任何其他人做new SomeObject()
而不管它是否是静态引用。拥有单例类的想法是控制实例。例如,如果您创建构造函数private
,则无法执行new
来创建新实例。因此,您正在控制实例的创建。
答案 1 :(得分:4)
主要区别在于单例是一个普通实例,您可以将其用作参数。单身人士也可以实现接口。
利玛
答案 2 :(得分:1)
如果您认为自己可能想要利用继承或接口,那么您将需要使用实际实例而不是静态类。例如,如果您想将实例设置为执行与通常稍微不同的操作,该怎么办?您可以将单例值设置为接口的不同实现的实例,或者设置为覆盖某些功能的子类。访问该单例实例的所有代码都可以以完全相同的方式使用它,但其行为可以更改。
但是,我会补充一点,单身人士和静态课程现在都被认为是一种反模式。最好使用依赖注入,如果你想要单例行为,只需使用单例绑定。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一样。不过,我会重申我先前的说法:单身人士是一种反模式。喜欢依赖注入。
答案 3 :(得分:1)
到目前为止有几个好的答案。
这篇When is a Singleton not a Singleton文章很好地表达了这个概念。
以下是一些额外的差异:
答案 4 :(得分:0)
首先,您要检查对象是否具有多态(例如人类的状态正在读取,正在唱歌)。然后,您可以决定使用Singleton Object。
Singleton提供了一种控制内存占用的好方法。在jdk中,运行时类为singleton。通过Runtime.getRuntime()
得到对象。
为什么那里需要多个运行时对象。
仅一次运行。可以执行该过程。