【问题标题】:Singleton instantiation creating multiple objects单例实例化创建多个对象
【发布时间】:2015-11-10 08:46:00
【问题描述】:

我正在尝试学习单例设计模式,并且遇到了以下示例。但是,似乎我能够创建该类的多个实例。

我认为 Singleton 的意义在于只允许在任何给定时间创建一个类的单个实例。谁能解释我在这里缺少什么?如何验证在任何给定时间只创建了一个对象?

public class ChocolateBoiler {
    private boolean empty;
    private boolean boiled;

    private static ChocolateBoiler uniqueInstance;

    private ChocolateBoiler(){
        empty = true;
        boiled = false;
    }

    public static synchronized ChocolateBoiler getInstance(){
        if(uniqueInstance == null){
            uniqueInstance = new ChocolateBoiler();
        }
        return uniqueInstance;
    }

    public void fill(){
        if(isEmpty()){
            System.out.println("filling");
            empty = false;
            boiled = false;

        }
        System.out.println("already full");
    }

    public boolean isEmpty(){
        System.out.println("empty");
        return empty;

    }

    public boolean isBoiled(){
        System.out.println("boiled");
        return boiled;
    }

    public void drain() {
        if (!isEmpty() && isBoiled()) {
            System.out.println("draining");
            empty = true;
        }
        System.out.println("already empty");
    }

    public void boil(){
        if(!isEmpty() && isBoiled() ){
            System.out.println("boiled");
            boiled = true;
        }
        System.out.println("either empty or not boiled?");
    }

    public static void main(String[] args) {
        ChocolateBoiler boiler1 = new ChocolateBoiler();
        boiler1.fill();
        boiler1.boil();
        boiler1.boil();
        boiler1.drain();
        boiler1.drain();
        boiler1.isEmpty();


        System.out.println("\nboiler 2");
        ChocolateBoiler boiler2 = new ChocolateBoiler();
        boiler2.fill();

        System.out.println("\nboiler 1");
        boiler1.isBoiled();
    }
}

【问题讨论】:

  • 你认为它为什么会创建两个实例?
  • 你的单例模式是正确的,你应该从其他类中调用它

标签: java oop design-patterns singleton


【解决方案1】:

ChocolateBoiler 类中,您可以访问私有构造函数,因此您可以创建任意数量的实例(正如您在main 方法中所展示的那样)。

单例模式的要点在于,在您的类之外,只能获得一个ChocolateBoiler 实例(通过getInstance 方法),因为无法从外部访问私有构造函数。

【讨论】:

  • 明白了!我知道这将是一件简单的事情。谢谢。
  • 所以我尝试使用ChocolateBoiler tmp = ChocolateBoiler.getInstance();,但遇到了一个奇怪的小错误Exception in thread "main" java.lang.NoSuchMethodException: DesignPatterns.Singleton.ChocolateBoiler.main([Ljava.lang.String;) at java.lang.Class.getMethod(Class.java:1786) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:125),即throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes)); 有什么想法吗?
  • @MichaelQuatrani 看起来像是清理旧编译的问题。您是否将主要方法移至新类?你的新代码是什么样子的?
  • 是的,这一定正是发生的事情。我将 main 从 ChocolateBoiler 移到一个单独的类中。
猜你喜欢
  • 2012-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多