What is the best approach for using an Enum as a singleton in Java?
Asked Answered
G

4

88

Building on what has been written in SO question Best Singleton Implementation In Java - namely about using an enum to create a singleton - what are the differences/pros/cons between (constructor omitted)

public enum Elvis {
    INSTANCE;
    private int age;

    public int getAge() {
        return age;
    }
}

and then calling Elvis.INSTANCE.getAge()

and

public enum Elvis {
    INSTANCE;
    private int age;

    public static int getAge() {
        return INSTANCE.age;
    }
}

and then calling Elvis.getAge()

Gravedigger answered 9/1, 2009 at 12:32 Comment(0)
R
96

Suppose you're binding to something which will use the properties of any object it's given - you can pass Elvis.INSTANCE very easily, but you can't pass Elvis.class and expect it to find the property (unless it's deliberately coded to find static properties of classes).

Basically you only use the singleton pattern when you want an instance. If static methods work okay for you, then just use those and don't bother with the enum.

Ridenhour answered 9/1, 2009 at 12:39 Comment(16)
Why not bother with the enum? Is there a better way to do singeltons in java5+?Shelleyshellfire
@Shelleyshellfire (re)read the answer; he says to use enums when you must have a singleton but to avoid singleton if you can make do with static methodsCrux
@MiserableVariable I commented on this over a year ago. Cant really remember what the context I was referring to.Shelleyshellfire
doesn't answer the asked questionKalliekallista
@Thufir: It answers the "what's the difference" part - which appears to be what the OP was most interested in, given that the answer was accepted.Ridenhour
@Jon, and what is the benefit of using singleton pattern of enum, comparing to using singleton pattern of a normal Java class?Adviser
@LinMa: It plays better with serialization, apart from anything else. Effective Java 2nd edition goes into more details.Ridenhour
Thanks @Jon, which specific part of Effective Java 2nd edition do you mean? Thanks.Adviser
@LinMa: I can't remember the specific section number, but there's a part which explicitly recommends using enums for singletons, with detailed reasons.Ridenhour
@Jon, no worries and I will take a look for the book. Have a good weekend.Adviser
@Jon, I borrowed a book of Effective Java edition 2, looked through section of Enum (chapter 6) and Serialization (chapter 11), but do not get any details about benefit of using Enum on serialization. If you have more details, appreciate for share. Have a good weekend. :)Adviser
@LinMa: Item 3 doesn't give as many details as I'd hoped, but does say "This approach [enums] 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." (Just before that, it gives an example of the serialization code you should write to make a serializable singleton in a non-enum case.)Ridenhour
@Lin: Effective Java is written in items... This is in item 3.Ridenhour
@Jon, sorry asked a stupid question. I read the section in the book and it said it offers serialization for free for INSTANCE of enum, what does it mean?Adviser
@LinMa: It means that if you serialize the instance, then deserialize, the singleton nature will be preserved (i.e. you'll still get a reference to the instance that other code would refer to). If you have any more questions, I suggest you ask in a new post.Ridenhour
@Jon, for sure and will follow your advice. We can discuss here => https://mcmap.net/q/25246/-instance-in-a-java-enum, have a good weekend. :)Adviser
R
69

A great advantage is when your singleton must implements an interface. Following your example:

public enum Elvis implements HasAge {
    INSTANCE;
    private int age;

    @Override
    public int getAge() {
        return age;
    }
}

With:

public interface HasAge {
    public int getAge();
}

It can't be done with statics...

Rigby answered 9/1, 2009 at 14:5 Comment(1)
It can be done with statics... public static final HasAge INSTANCE = new HasAge() { private int age; @Override public int getAge() { return age; } }; ... so I'm still wondering what is good or better about the enum method. I suppose if you needed to implement two interfaces?Trev
I
9

(Stateful) Singletons are generally used to pretend not to be using static variables. If you don't actually use the publicly static variable then you will fool less people.

Ils answered 9/1, 2009 at 12:57 Comment(0)
E
8

I would choose the option which is the simplest and clearest. This is somewhat subjective, but if you don't know what is clearest, just go for the shortest option.

Estancia answered 19/7, 2009 at 11:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.