15

I read Effective Java and there it's stated that a singleton is best implemented using enum.

This approach is functionally equivalent to the public field approach, except that it is more concise, provides the serialization machinery for free, and provides an ironclad guarantee against multiple instantiation, even in the face of sophisticated serialization or reflection attacks. While this approach has yet to be widely adopted, a single-element enum type is the best way to implement a singleton.

Still, this seems like a trade-off to achieve on the fly serialization and true single instance, but you lose the more friendly OOP approach of a classical singleton. Enums can't be inherited, can implement only an interface and if you want to provide a skeleton class you need to create a helper class.

So, why should we accept enum as the best implementation for a singleton, other than the reasons stated above?

Boann
  • 48,794
  • 16
  • 117
  • 146
sa_vedem
  • 757
  • 1
  • 7
  • 16
  • 1
    What kind of "skeleton class" are you talking about? I can't remember *every* subclassing another non-Object class in order to create a singleton - it almost *always* implements an interface. (I'm not saying it doesn't happen - I just can't remember doing it.) – Jon Skeet Aug 06 '12 at 15:57
  • 1
    The real question is, why do you require a singleton in the first place? And if you do require it, how would a singleton extend another class? Would that class also be a singleton? If not, how does that work? If it is, what happens if someone else extends it too? You'll have two instances of a singleton base class. – biziclop Aug 06 '12 at 15:59
  • could be useful. http://stackoverflow.com/questions/4992893/using-enums-to-implement-utility-classes-and-singletons – Ahmet Karakaya Aug 06 '12 at 15:59
  • Singleton is a seriously deprecated anti-pattern, I think the only fair use for this is to implement constants, which enums do handily. – djechlin Aug 06 '12 at 16:00
  • @djechlin, I don't think the Singleton pattern shall be a priori deprecated. It is, IMHO, the best way to implement other useful pattern such as the Observer. In the IOS framework for instance the app delegate is a singleton. Moreover the NSNotification service (which so well decouple communicating objects) is actually implemebted by mans of a Singleton (the NSNotificationCenter). – Andrea Sindico Aug 06 '12 at 16:08
  • @Jon Skeet what do you mean by non-Object class? – sa_vedem Aug 06 '12 at 16:20
  • 1
    @sa_vedem I guess he means any class apart from java.lang.Object. – biziclop Aug 06 '12 at 16:22

3 Answers3

16

this seems like a trade-off to achieve on the fly serialization

For me it's a lot simpler and more concise to write something like

enum Singleton {
    INSTANCE;
}

If you have a need to write a lot more code or introduce complexity then do so, but this is rarely required IMHO.

you lose the more friendly OOP approach of a classical singleton.

I find using fields to be simpler.

Enums can't be inherited,

True, but having multiple singletons is suspect in itself. Enums can inherit from interfaces which allows you to swap one implementation for another.

If you want to provide a skeleton class you need to create a helper class

A helper class doesn't have any state. A skeleton class might have some state in which case you need delegation.

BTW: You can use enum for helper classes

enum Helper {;
    public static my_static_methods_here;
}

why should we accept enum as the best implementation for a singleton

I would follow the YAGNI principle. Only develop what you need, not what you imagine you might need.

Boann
  • 48,794
  • 16
  • 117
  • 146
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
16

Enums can't be inherited

And it's one of the best parts of enums being singletons.

If you can inherit from a singleton, it's not a singleton any more.

Boann
  • 48,794
  • 16
  • 117
  • 146
dantuch
  • 9,123
  • 6
  • 45
  • 68
11

There was a similar discussion at stackoverflow a while ago: What is an efficient way to implement a singleton pattern in Java?

The accepted answer provides good links on that topic:

Joshua Bloch explained this approach in his Effective Java Reloaded talk at Google I/O 2008: link to video. Also see slides 30-32 of his presentation (effective_java_reloaded.pdf):

The main point is that it is quite hard to write a singleton that is a real singleton. Enum values are guaranteed to exist only once as defined in the Java Language Specification §8.9:

An enum type has no instances other than those defined by its enum constants.

Stefan Ferstl
  • 5,135
  • 3
  • 33
  • 41
  • Where did you find this sentence? Enum values are guaranteed to exist only once. Is there official documentation? – Yan Khonski Mar 04 '19 at 14:01
  • @YanKhonski This is part of the Java Language Specification: https://docs.oracle.com/javase/specs/jls/se11/html/jls-8.html#jls-8.9 : "An enum type has no instances other than those defined by its enum constants. It is a compile-time error to attempt to explicitly instantiate an enum type (§15.9.1)." I updated my answer accordingly. – Stefan Ferstl Mar 04 '19 at 15:11