Singleton with Arguments in Java Singleton with Arguments in Java java java

Singleton with Arguments in Java


I'll make my point very clear: a singleton with parameters is not a singleton.

A singleton, by definition, is an object you want to be instantiated no more than once. If you are trying to feed parameters to the constructor, what is the point of the singleton?

You have two options. If you want your singleton to be initialized with some data, you may load it with data after instantiation, like so:

SingletonObj singleton = SingletonObj.getInstance();singleton.init(paramA, paramB); // init the object with data

If the operation your singleton is performing is recurring, and with different parameters every time, you might as well pass the parameters to the main method being executed:

SingletonObj singleton = SingletonObj.getInstance();singleton.doSomething(paramA, paramB); // pass parameters on execution

In any case, instantiation will always be parameter-less. Otherwise your singleton is not a singleton.


I think you need something like a factory to have objects with various parameters instantiated and reused. It could be implemented by using a synchronized HashMap or ConcurrentHashMap map a parameter (an Integer for an example) to your 'singleton' parameterizable class.

Although you might get to the point where you should use regular, non-singleton classes instead (for example needing 10.000 differently parametrized singleton).

Here is an example for such store:

public final class UsefulObjFactory {    private static Map<Integer, UsefulObj> store =        new HashMap<Integer, UsefulObj>();    public static final class UsefulObj {        private UsefulObj(int parameter) {            // init        }        public void someUsefulMethod() {            // some useful operation        }    }    public static UsefulObj get(int parameter) {        synchronized (store) {            UsefulObj result = store.get(parameter);            if (result == null) {                result = new UsefulObj(parameter);                store.put(parameter, result);            }            return result;        }    }}

To push it even further, the Java enums can be also considered (or used as) parametrized singletons, although allowing only a fixed number static variants.

However, if you need a distributed1 solution, consider some lateral caching solution. For example: EHCache, Terracotta, etc.

1 in the sense of spanning multiple VMs on probably multiple computers.


You can add a configurable initialization method in order to separate instantiation from getting.

public class Singleton {    private static Singleton singleton = null;    private final int x;    private Singleton(int x) {        this.x = x;    }    public static Singleton getInstance() {        if(singleton == null) {            throw new AssertionError("You have to call init first");        }        return singleton;    }    public synchronized static Singleton init(int x) {        if (singleton != null)        {            // in my opinion this is optional, but for the purists it ensures            // that you only ever get the same instance when you call getInstance            throw new AssertionError("You already initialized me");        }        singleton = new Singleton(x);        return singleton;    }}

Then you can call Singleton.init(123) once to configure it, for example in your app startup.