1

I want to use the following pattern to create a singleton in 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()? As in 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.

The object I am passing in is the android application context.

assylias
  • 321,522
  • 82
  • 660
  • 783
Cote Mounyo
  • 13,817
  • 23
  • 66
  • 87

4 Answers4

5

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.

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).


Usual disclaimer: Singletons are evil.
Additional resource: Google guide to writing testable code (in case you were not convinced the first time).

Community
  • 1
  • 1
assylias
  • 321,522
  • 82
  • 660
  • 783
0
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;
        }
}
Joris W
  • 517
  • 3
  • 16
0

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.

Community
  • 1
  • 1
user2587106
  • 315
  • 1
  • 5
-1

Why not get rid of SingletonHolder use factory pattern. You will have to decide what to do, when try to call getInstance twice, but with different 'stuff'.

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
   }
}
Ayub Malik
  • 2,488
  • 6
  • 27
  • 42