简体   繁体   English

使用静态内部类创建java单例

[英]Creating java singleton with static inner class

I want to use the following pattern to create a singleton in java 我想使用以下模式在java中创建单例

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

        /**
        * SingletonHolder is loaded on the first execution of Singleton.getInstance() 
        * or the first access to SingletonHolder.INSTANCE, not before.
        */
        private static class SingletonHolder { 
                public static final Singleton INSTANCE = new Singleton();
        }

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

But what happens when the private constructor I want to call is 但是当我想调用的私有构造函数发生时会发生什么

 private Singleton(Object stuff) {... }

How do I pass stuff to INSTANCE = new Singleton() ? 如何将stuff传递给INSTANCE = new Singleton() As in INSTANCE = new Singleton(stuff); 如在INSTANCE = new Singleton(stuff);

Rewriting the above snippet: 重写上面的代码段:

public class Singleton {
        // Private constructor prevents instantiation from other classes
        private Singleton(Object stuff) { ... }

        /**
        * SingletonHolder is loaded on the first execution of Singleton.getInstance() 
        * or the first access to SingletonHolder.INSTANCE, not before.
        */
        private static class SingletonHolder { 
                public static final Singleton INSTANCE = new Singleton();
        }

        public static Singleton getInstance(Object stuff) {
                return SingletonHolder.INSTANCE;//where is my stuff passed in?
        }
}

EDIT: 编辑:

for those of you claiming this pattern is not thread safe, read here: http://en.wikipedia.org/wiki/Singleton_pattern#The_solution_of_Bill_Pugh . 对于那些声称此模式不是线程安全的人,请阅读: http//en.wikipedia.org/wiki/Singleton_pattern#The_solution_of_Bill_Pugh

The object I am passing in is the android application context. 我传入的对象是android应用程序上下文。

If you really want a singleton, there should be only one instance of it (duh!). 如果你真的想要一个单身,那么它应该只有一个实例(呃!)。 If you add a parameter to getInstance you probably expect the returned instance to be different (otherwise there is no need for a parameter) which defeats the purpose. 如果向getInstance添加一个参数,您可能希望返回的实例不同(否则不需要参数),这会使目的失败。

If your goal is to add some configuration when the only instance is created, the simplest way would be to have your singleton query for the configuration information when it is instantiated: 如果您的目标是在创建唯一实例时添加一些配置,最简单的方法是在实例化时对配置信息进行单例查询:

public static final Singleton INSTANCE = new Singleton(getConfiguration());

where getConfiguration returns what is needed (whether by reading a file or forwarding some other variable for example). 其中getConfiguration返回所需内容(例如,通过读取文件或转发其他变量)。


Usual disclaimer: Singletons are evil . 通常的免责声明: 单身人士是邪恶的
Additional resource: Google guide to writing testable code (in case you were not convinced the first time). 其他资源: Google编写可测试代码的指南 (如果您第一次不相信)。

public class Singleton {
        private static Singleton singleton;

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

        public void addStuff(Object stuff){}    

        public static Singleton getInstance() {
                 if(singleton == null) singleton = new Singleton()
                 return singleton;
        }
}

and use it as: 并将其用作:

 Singleton s = Singleton.getInstance();
 s.addStuff(stuff);

or an alternative 或另类

public class Singleton {
        private static Singleton singleton;

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

        public static void redefine(Object stuff){

             singleton = new Singleton(stuff) // choose constructor based on parameters
        }


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

You might want to read 你可能想读

a singleton with parameters is not a singleton 带参数的单例不是单例

The first answer argues why a >>singleton with parameters<< is not a singleton, and doesn't come near a singleton. 第一个答案论证了为什么带有参数<<的单例不是单例,并且不接近单例。

Why not get rid of SingletonHolder use factory pattern. 为什么不摆脱SingletonHolder使用工厂模式。 You will have to decide what to do, when try to call getInstance twice, but with different 'stuff'. 当你尝试两次调用getInstance时,你必须决定做什么,但是使用不同的'东西'。

public class Singleton {

    private static Singleton singleton
    private final Object stuff;

    private Singleton(Object stuff) {
        this.stuff = stuff;
    }

    public static synchronized Singleton getInstance(Object stuff) {
         if (singleton == null) {
             singleton = new Singleton(stuff);
             return singleton;
         }

         return singleton; // or throw error because trying to re-init
   }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM