4

As is now well known the recommended way for creating a singleton in java is via an enum (see for instance here)

But (for example in this answer) it seems to be considered (by @MikeAdler who replied to me in the comments) the right thing to have the enum in the singleton class (see for instance here for a full example, or the code given below). I do not seem to really understand the need/use of this - can someone please elaborate (and preferably give the correct dialect for this idiom) ?

public class Enclosing {

    private  Enclosing() {}

    static enum Singleton {
        INSTANCE;

        private static final Enclosing  singleton = new Enclosing();

        public Enclosing getSingleton() {
            return singleton;
        }
    }
}

EDIT : one would get the singleton by Enclosing.Singleton.INSTANCE.getSingleton();

Community
  • 1
  • 1
Mr_and_Mrs_D
  • 32,208
  • 39
  • 178
  • 361
  • 1
    That's if you want a singleton class, not a singleton enum. – Dave Newton Oct 14 '12 at 14:27
  • @DaveNewton : could you elaborate in an answer ? I remind you that enums are special classes - and that the singleton will be an instance of some class anyway. What does it mean a "singleton class" ? – Mr_and_Mrs_D Oct 14 '12 at 14:32
  • 1
    If you need, or have, a specific class, and you want it to be a singleton, this is one of the easiest ways to implement that. I don't really need to be reminded what an enum is, but thanks. – Dave Newton Oct 14 '12 at 14:36
  • @DaveNewton Oh don't get me wrong :) Say I was reminding myself :D - still I do not really get the difference - why not create the class like this and not as a top level enum ? – Mr_and_Mrs_D Oct 14 '12 at 14:39
  • 1
    I told you--if you already have, or for some reason specifically need, a given class, and you don't want an enum. – Dave Newton Oct 14 '12 at 14:42

2 Answers2

2

You would nest a Singleton when you wanted to perform lazy-loading of it, say for testing reasons:

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

    static enum SingletonHolder {
        INSTANCE;
    }
}

Read more about it here: http://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom

Community
  • 1
  • 1
Garrett Hall
  • 29,524
  • 10
  • 61
  • 76
  • Makes sense - could you please elaborate on the mechanism ? As I see from your code the singleton would be created when the class `Singleton` is loaded for the first time while a top level enum would create the INSTANCE on application load ? – Mr_and_Mrs_D Oct 14 '12 at 14:36
  • Why is this better than using a plain old enum ? As I don't think it is. – NimChimpsky Oct 14 '12 at 14:39
  • @Nim : cause the enum singleton is only created when/if needed (I guess - not sure how the class loader works) – Mr_and_Mrs_D Oct 14 '12 at 14:41
  • Let's say SingletonHolder has static initialization that takes a long time. If I want to call other static methods on Singleton without going through initialization I can. This may be useful if I want to inject a different SingletonHolder INSTANCE for unit testing. – Garrett Hall Oct 14 '12 at 14:41
  • I don't see how static initializers are relevant. You can call static methods of enum without a new instance, and you can inject a different enum if you like. I don't get the advantage of your code at all. – NimChimpsky Oct 14 '12 at 14:45
  • An enum is lazy loaded anyway by the class loader. – NimChimpsky Oct 14 '12 at 15:44
  • @NimChimpsky : yes but it will be loaded as soon as any of its methods are called. Here you can call any of the static methods of `Singleton` and still not have the `SingletonHolder` initialized. Do read the linked wikipedia article (the How it works section) and please let me know if having objections. At Garrett Hall : I would appreciate some more concrete testing example - I do think I have to accept your answer though :) – Mr_and_Mrs_D Oct 14 '12 at 22:29
  • A very very nice explanation of the "Initialization-on-demand holder idiom" aka [Lazy Initialization Holder Class by Josh Bloch](http://youtu.be/pi_I7oD_uGI?t=39m34s). I'd still appreciate some testing code, showing the need for this pattern :) – Mr_and_Mrs_D Jun 01 '13 at 12:41
1
public enum Foo {
   INSTANCE;
}

is the simplest and best way to get a singleton post-java 5. The code you posted is just unnecessarily complex, I don't see any advantage of it over just using an enum.

NimChimpsky
  • 46,453
  • 60
  • 198
  • 311