Update after some comments: this post is not a discussion whether to use Singleton or not. It’s not a discussion on why Singleton might be an anti-pattern. It’s just an example on an alternative implementation of Singleton in Java. Just that.
There are two classic ways to implement Singleton pattern in Java: public final instance field or static factory method to create/get instance.
However there is one more, probably the best way to do it if you are using Java >= 1.5. You can use Enum – this way you get Singleton functionality easily and don’t have to think about serialization as you get it for free:
package electro;
public enum YourSingleton {
INSTANCE;
public void doStuff(String stuff) {
System.out.println("Doing " + stuff);
}
}
Now you can use it and be completely sure it’s Singleton:
YourSingleton.INSTANCE.doStuff("some stuff");
Thanks to Joshua Bloch and his great book “Effective Java Second Edition“.
cool idea
holy good idea batman!!
[...] Stuff on popurls.com and almost choked at seeing an link on the DZone feed to an article entitled Singletons in Java – the proper way. Generally, I’m of the opinion that we’re awash in overuse and certainly near abusive [...]
Don’t use singletons if you can avoid it. There are far better alternatives. Think about dependency injection (and others).
Tex, it’s not about using them or not using them, it’s about how to use them (if you need it) the most elegant way.
And of course this implementation fails as well as most others when non-trivial class-loading setup enters the picture. :)
Well, that’s a very nice idea!!!
I agree that if you can avoid it (and generally, of course you can!) do it! (but that’s another, unrelated issue)
I also agree that this post was about the idea itself; and if you really want a Singleton implementation, this is the most elegant thing I’ve seen in a while (not necessarily related to Singletons, but in general)
Nice job!
Tavi
This idea can also be seen in the 2nd Edition (Java6-compliant) of Effective Java (good book!).
[...] Manière élégante de faire des singletons avec des énumérations. [...]
I read that in Effective Java too, and my first thought was something in the lines of “you gotta be kidding me”. I know, that doing it with an enum solves the problem of deserialized instances and guarantees only one instance in a classloader. But hey: It is an enum, not a class. There is meaning to the reader of your code, that something is an enum. It enumerates something. It is not a singleton. And by the way, you cannot extend an enum type. So, is this really a good idea?
Tech Per, in most of the cases you really don’t want Singleton to be extended. Classical Singleton has private constructor!
One problem I see with this is that IT IS NOT AN ENUM. It is obfuscated code.
Although, this seems to be pretty elegant for the modern JDKs, ask yourself if a Singleton is still a pattern your project should use.
Some thoughts about this question from the architects perspective:
http://blog.rainer.eschen.name/2006/12/15/how-to-decontaminate-a-singleton/
Creative idea.
But as what others mentioned to use an enum represent something which is not an enum will obfuscate the code. Cause un-necessary confusion for the source code reader.
Another issue is this kind of singleton is no different as using class with static members.
One reason why we use singleton is to make the class lazy instantiate to break possible recursive initialization of classes because of cross dependencies. Singleton objects should be created only when it’s used rather than when the class is loaded.
jianwu_chen, it’s not my idea, it’s Joshua Bloch’s :)
I agree about the source code confusion, but we have comments for that.
And about “this kind of singleton is no different” is not true, it’s different. For classic Singleton to be serialiazable you have to implement Serializable and declare all instance fields transient and provide a readResolve method. In other case after serialization deserialization you will get a new instance.
With enum approach you don’t have to think about it.
[...] [Este artículo es una traducción de Singleton in Java - the proper way.] [...]
Well…
Actually, ahem, I also came up with the idea of using a single enum constant for the Singleton implementation in Java 5/6 around May 2007 during the writing of my Master Thesis, which has been publicly available on the net since January 2008. Well before Bloch published the second version of his excellent book (which I have not read yet!) – though he most certainly thought of it looong before, I know! :)
So, in my megalomania I dubbed this as the Singleton-as-Single-Constant idiom… :)
See for yourself at http://www.rode.dk/thesis
Regards – Gunni
(flaming commence…)
To use or not use a Sigleton seems to generate lots of discussion.
For a Swing app I needed single-instances of certain classes at the application level.
I use Guice for other apps but guice.jar is 544k; I used pico also but pico.jar is 249k so I decided on an enum-based class to implement this Singleton/Cache function at the application level.
Enclosed below is the class I am using now; it works but I do not know how safe it is and whether it is useful/safe in an environment such as a servlet for application-level objects: any comments, ideas; thanks for the post:
public enum ZFactory { KEYVALUEPAIRS() { public Object get() { if (kvp == null) kvp = new KeyValuePairs(); return kvp; } }, ENCODERDECODER() { public Object get() { if (ed == null) ed = new EncoderDecoder(); return ed; } }, BARCODEIMAGE() { public Object get() { if (bci == null) bci = new BarCodeImage(); return bci; } }, JTABBEDPANE() { public Object get() { if (tp == null) tp = new JTabbedPane(); return tp; } }; protected KeyValuePairs kvp = null; protected EncoderDecoder ed = null; protected BarCodeImage bci = null; protected JTabbedPane tp = null; public abstract Object get(); }Hi, J.F. Zarama,
I think it is safe if you’re not using multiple calssloaders.
As far as comments and ideas:
1. I think it would be better (from design perspective) to have a separate factory (which would serve one purpose) and four separate enum singletons (also one purpose each). Of course all four objects should be polymorphic, in other case I don’t see any point in having a factory at all.
2. Your enum doesn’t use constructor parameters, so you can leave out the ‘()’ near instances, like KEYVALUEPAIRS {…
3. Idea from 2. – you can create needed objects in enum constructor like:
public enum ZFactory { ... KEYVALUEPAIRS(new KeyValuePairs()), JTABBEDPANE(new JTabbedPane()); ZFactory(Object obj) { this.obj = obj; } private Object obj; public Object get() { return obj; } }And of course it’s better to refactor it to 1. with separate factory.
Call me blasphemous but I think Dependency Injection is a bit over-hyped. So many people dis on a simple singleton because they heard “you shouldn’t use it” without even understanding why. They aren’t that bad. Most people using DI aren’t EVERY even swapping out implementations of their classes.. they just it because they can, and it solved nothing but actually in some cases make things more difficult (just one more place to have to figure out where I’m getting things from.)
I’m not against DI, but use it because it makes sense to do so – ie you plan to swap out in testing and use different implementations of your interfaces. I’m curious what % of people are doing this? I test my services and daos but I’m not testing mock ones.. I want to test the real thing.
For the poster commenting about static methods instead, there is a big difference: If I uses singletons I can implement an Interface and thus provide a different implementation of my singleton if need be. You can’t do that with a class with static methods.
mmh…
I can use some books on my chair to lift up my sitting… But that’s not their purpose (isn’t it?). Using enum for a singleton is not a more elegant way I think… It’s only an escamotage…
From http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html
“So when should you use enums? Any time you need a fixed set of constants. That includes natural enumerated types (like the planets, days of the week, and suits in a card deck) as well as other sets where you know all possible values at compile time, such as choices on a menu, rounding modes, command line flags, and the like. It is not necessary that the set of constants in an enum type stay fixed for all time. The feature was specifically designed to allow for binary compatible evolution of enum types. ”
That’s why enums doesn’t fit for singleton…
Fausto Mancini,
your quote says that one should use enums anytime one needs “a fixed set of constants”.
Well, singleton is a pretty fixed set isn’t it? Actually, in Set theory, the term “singleton” reffers to a set with one member.