Java 单例模式

17

编辑:已回答-错误在于方法不是静态的

我使用了单例设计模式

 public class Singleton {
   private static final Singleton INSTANCE = new Singleton();

   // Private constructor prevents instantiation from other classes
   private Singleton() {}

   public static Singleton getInstance() {
      return INSTANCE;
   }
 }

我的问题是如何在另一个类中创建一个Singleton类的对象?

我尝试过:

Singleton singleton = new Singleton(); 
// error - constructor is private
Singleton singleton = Singleton.getInstance();
// error - non-static method cannot be referenced from a static context

正确的代码是什么?

谢谢, Spencer


有些人在getInstance()中避免使用get,因为这违反了JavaBean命名约定。另一种替代方法是instance() - Basil Bourque
8个回答

26
Singleton singleton = Singleton.getInstance();

这是正确的方法。确保你的 getInstance() 方法确实是 static

由于你的 Singleton 实现远非安全 - 通过反射可以实例化你的对象,你可能想要创建一个基于 enum 的单例模式。


这正是我所做的,忘记将方法设为静态的了。谢谢。 - Spencer
我认为不需要通过反射来保护代码免受滥用。那些使用反射的人应该知道其中的危险。 - Bart van Heukelom
2
@Bart van Heukelom 理论上我完全同意你的观点。但是不幸的是,在实践中这通常并不正确 :) - Bozho

3
Singleton singleton = Singleton.getInstance();应该是有效的,根据你提供的代码,那个错误没有意义;你确定你正确地报告了吗?(如果你忘记将getInstance方法设为静态的,那么这是有意义的,但你已经在上面的代码中完成了。)
你提供的类的代码是正确的。
最后,一个概念性的注释:首先,你不是“创建一个Singleton类的对象”——这就是Singleton模式的全部意义。 :) 你只是得到了对现有对象的引用。

2
这是一个例子:
 Singleton singleton = Singleton.getInstance();

应该可以工作。这就是在Java中调用静态方法的方式。而getInstance()方法被声明为static。你确定你正在使用完全相同的Singleton类吗?或者你可能已经导入了某个其他包中同名的类。


2

由于我们不想允许多个副本被访问,所以需要手动实例化对象,但是我们需要保留对单例的引用,以便后续对访问方法的调用可以返回单例(而不是创建新的)。

Singleton singleton = Singleton.getInstance();

访问任何单例对象的正确方法。


2
  1. 由于构造函数是私有的,因此使用构造函数创建对象没有意义。
  2. 您应该使用public static Singleton getInstance(),但实现方式不太正确。

    if (instance == null) {
    instance = new Singleton();
    }
    return instance;

这是正确的方式。它确保在需要时创建实例,或者仅返回现有实例。您的代码也会做同样的事情,但这样会增加可读性。


1

使用这种方式没有任何问题。

Singleton singleton = Singleton.getInstance();
// error - non-static method cannot be referenced from a static context

这是从类中获取单例对象的方法。一定还有其他内容。请发布更多细节。


1

仍然可以创建多个类的实例,如下所示:

Singleton.getInstance().clone()

0

由于 getInstance() 方法是“静态的”,而 instance 字段也是如此,因此您可以使用 Singleton.getInstance();而不需要创建类的新实例。这就是 Singleton 的目的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接