什么时候我们应该在Java中使用Singleton类?

时间:2011-08-26 16:36:02

标签: java singleton

根据我的想法,当我们在整个应用程序中共享相同的对象状态时,我们应该将类创建为Singleton。在这种情况下,我们希望用户每次都限制创建新实例,以便它们不能维持多个状态。同意。但是通过将实例变量声明为静态可以实现相同的行为。对我来说,无论是cacheobjectcontainerlogger还是Classloader类,它看起来也会起到同样的作用。

请帮助我理解上面的概念静态实例变量无法解决的目的,并且需要将类声明为Singleton?

已编辑的部分

好的,让我更清晰一些。单例类的目的是在jvm中只保留一个单例类的实例。同意。但我试图想出为什么我们只想保留一个实例的原因。 原因有两个:

1)创建对象可能很昂贵。所以我们只想保留一个实例。在这种情况下同意将实例变量声明为静态并不能解决任何问题。

2)我们希望跨应用程序共享相同的对象状态。我认为这是将类声明为单例的主要目的。但它可以通过将实例变量声明为静态来实现。

但看起来像1是将任何类声明为静态而不是原因2的主要原因,因为它也可以用静态变量实现。

这是正确的吗?

5 个答案:

答案 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()相同,则无关紧要。在那种情况下:

  1. 从语义角度来看,当另一个程序员看到new SessionManager()时,他们期待正在创建new。系统中的每个SessionManager总是会产生相同的systemName并不是很明显。因此,单身可能更为可取,只是为了让消费者更明白他们将处理单身国家。
  2. 创建new SessionManager()时会产生非常小的开销,以后必须进行垃圾回收。
  3. 除此之外,这种方法基本上具有相同的优点和缺点,就像使用Singleton一样。不过,我会重申我先前的说法:单身人士是一种反模式。喜欢依赖注入。

答案 3 :(得分:1)

到目前为止有几个好的答案。

这篇When is a Singleton not a Singleton文章很好地表达了这个概念。

以下是一些额外的差异:

  • 单身人士可以是有状态的,但静态变量却不能。
  • 单例类可以是子类

答案 4 :(得分:0)

首先,您要检查对象是否具有多态(例如人类的状态正在读取,正在唱歌)。然后,您可以决定使用Singleton Object。

Singleton提供了一种控制内存占用的好方法。在jdk中,运行时类为singleton。通过Runtime.getRuntime()得到对象。  为什么那里需要多个运行时对象。 仅一次运行。可以执行该过程。