Implementing Singleton with an Enum (In Java)

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 (only implements)
  • Some predefined methods (like static values() and getName()) 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



Leave a reply



Submit