Implementing Singleton with an Enum (in Java)
This,
public enum MySingleton {
INSTANCE;
}
has an implicit empty constructor. Make it explicit instead,
public enum MySingleton {
INSTANCE;
private MySingleton() {
System.out.println("Here");
}
}
If you then added another class with a main()
method like
public static void main(String[] args) {
System.out.println(MySingleton.INSTANCE);
}
You would see
Here
INSTANCE
enum
fields are compile time constants, but they are instances of their enum
type. And, they're constructed when the enum type is referenced for the first time.
How to create a singleton class using enum
The differences between a class and an enum are not so big. I changed the first line of code to public enum
instead of public class
and added the name of your instance.
public enum Employee { // changed "class" to "enum"
INSTANCE; // added name of the (single) instance
private int id;
private String name;
Employee() {} // removed "public"
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getName() {
return name;
}
public void setName( String name ) {
this.name = name;
}
}
Please keep in mind, that singeltons, enum instances, static things might hinder you later on, if you want to run your code several times in one vm. Consider creating an instance of Employee
in your main class and pass it through your application.
Beside that, enums have some other special features:
- You cannot
extend
another class (onlyimplements
) - Some predefined methods (like
static values()
andgetName()
) are available - constructors can only be package private, or private
Singleton Pattern: Using Enum Version
public enum WirelessSensorFactory {
INSTANCE;
// all the methods you want
}
Here's your singleton: an enum with only one instance.
Note that this singleton is thread-safe, while yours is not: two threads might both go into a race condition or visibility problem and both create their own instance of your singleton.
How to enforce Singleton pattern using enum when class extends Another class
Since an enum is just a class, you can have it contain whatever you want (including a single instance of the "extended" class you want) and just expose it. You can control the singleton nature of anything with an enum.
public enum Elvis {
INSTANCE;
private Object wrappedObject = new Object();
public Object wrappedObject(){ return wrappedObject; }
public static void main(String args[]){
Object sortaSingledton = INSTANCE.wrappedObject();//there still can be only one
}
}
are java enums singleton?
Enums in java are classes with several constant instances of themselves. These are created like static final
variables. Accessing an enum constant returns a reference to the enum constant. It does not create a new instance of the enum constant.
Singleton enum with constants
In the enum declaration, ;
is used after the last enumerated value.
So here :
SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY;
INSTANCE;
this should be removed :
INSTANCE;
I want the enum to be singleton
It is already the case but for enum values (SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY
) which each one is a singleton.
The enum class itself is not a singleton and is not designed to be it.
Instead of trying to access the enum class in this way :
public Days getInstance() {
return INSTANCE;
}
Use just the class : Days
advantage of enum over class in singleton pattern
As explained by Joshua Bloch, the two approaches are functionally identical if your singleton is not serializable. Although you may wish to add code to your private Singleton
constructor to prevent reflection being used to create a second instance.
If your singleton is serializable, then the enum approach will provide all the necessary plumbing for free, whereas with the static field approach, you have to add that yourself.
In my view, there is no downside to adopting the enum approach.
Why enum singleton is lazy?
The first two linked answers (by Peter Lawrey and Joachim Sauer) both agree that enums are not lazily initialized. Answers in the third link are simply wrong about what lazy initialization means.
The recommendation to use enums as singletons originates from Josh Bloch's Effective Java. Notably, the chapter on enum singletons makes no mention of laziness. There is a later chapter dedicated to lazy initialization, that likewise makes no mention of enums. The chapter contains two highlights.
- If you need to use lazy initialization for performance on a static field, use the lazy initialization holder class idiom.
- If you need to use lazy initialization for performance on an instance field, use the double-check idiom.
Undoubtedly, enums would be another idiom on this list if they were in any way lazily initialized. In fact they are not, although confusion about the meaning of lazy initialization results in some incorrect answers, as the OP shows.
Related Topics
The Best Way to Print a Java 2D Array
Splitting on Comma Outside Quotes
How to Map an Entity Field Whose Name Is a Reserved Word in JPA
Powermockito Mock Single Static Method and Return Object
Executorservice That Interrupts Tasks After a Timeout
Is a Java Hashmap Search Really O(1)
Problems Using Maven and Ssl Behind Proxy
What Is the Backslash Character (\\)
Returning from a Finally Block in Java
Most Simple Code to Populate Jtable from Resultset
Get a Resource Using Getresource()
Auto Errors Detection in Intellij Idea
Java Securityexception: Signer Information Does Not Match
String's Maximum Length in Java - Calling Length() Method