我实现单例模式时出错

时间:2014-02-05 19:50:07

标签: java singleton

我测试了单例模式的实现,我觉得我无法弄清楚为什么IntelliJ会给我一个错误。这是代码。

public class CowSingleton {
    private static CowSingleton unique;
    private CowSingleton(){}

    //Only create new object if NOT already instantiated.

    public static CowSingleton getInstance(){
        if (unique == null){
            //creating unique object
            unique = new CowSingleton();
            System.out.println(unique);
        }
        //return Object
        return unique;
    }

    public String cowMoo(String str)
    {
       return str;
    }
}

以下是我如何称呼它:

CowSingleton cowSingleton = new CowSingleton.getInstance();
System.out.println(cowSingleton.cowMoo("Moooooo"));

我得到的错误:

"java: /Users/gpendleton/Personal/MyAnimals/src/Main.java:25: cannot find symbol
symbol  : class getInstance
location: class CowSingleton"

4 个答案:

答案 0 :(得分:7)

您不是自己创建实例;你正在推迟单身人士课程为你创造它。您调用getInstance()的代码不需要new关键字。毕竟,您正在调用静态方法,而不是自己创建对象。

删除new关键字。

CowSingleton cowSingleton = CowSingleton.getInstance();

答案 1 :(得分:2)

其他答案是正确的 - 但是Singleton模式的实现存在严重缺陷,并且会在多线程环境中以意想不到的方式中断。

最简单的方法是不要对单例进行延迟初始化,如果你真的必须进行延迟初始化,那么使用静态持有者来做:

public class CowSingleton {

    private static class SingletonHolder {
        private static CowSingleton unique;
    }

    private CowSingleton(){}

    public static CowSingleton getInstance(){
        return SingletonHolder.unique;
    }

    public String cowMoo(String str)
    {
        return str;
    }
}

这使用类加载器为您处理所有延迟初始化,线程安全等。它完全是线程安全的,因为它不需要同步或空检查。

答案 2 :(得分:1)

您正在调用可由类调用的static方法,因此请删除new关键字并更新代码,如下所示:

CowSingleton cowSingleton =  CowSingleton.getInstance();

答案 3 :(得分:1)

删除new关键字:

应该是

CowSingleton cowSingleton = CowSingleton.getInstance();

您正在调用static方法getInstance(),该方法提供(并且在您的Singelton变体中也创建)唯一的对象。

但请考虑“忘记”Singelton(模式) “设计模式”的主角Erich Gamma说,在他的书中包含这种模式并不是一个好主意。

原因是你不能很好地测试它,你不能重置它(只有反射)。 拥有一个诚实的全球对象通常比单身人士好得多。

这一切看起来不太好如果你必须引入“resetInstance()”或“resetSingleton()”方法。