11

I am trying to create a singleton class in Java. The best available solution with Java5 and above versions seems to be using enum. But I am not sure how to convert my class into a singleton class using enum. Following is my simplified class:

public class Employee { 
   private int id; 
   private String name; 
   public Employee() {} 
   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; 
   }
}

When I searched for answers in the net I found the following code:

public enum EasySingleton{
   INSTANCE;
}

But where are my class variables and methods? I am not sure how to implement this. I know we can provide methods to enum but where will my variables go? Any help on this would be really appreciated.

P.S.: Please don't debate if singleton are evil or anti-pattern. I am just curious on how to create a singleton using enum.

Pradeep S
  • 165
  • 2
  • 10
  • 2
    You would put them into the enum. But having a *mutable* enum would be very odd - and having a mutable singleton would be odd, too. `Employee` simply doesn't feel like a natural singleton. – Jon Skeet Jun 19 '15 at 14:38
  • Have a look [here](https://bitbucket.org/vadimvera/java-design-patterns/) and [here](https://bitbucket.org/vadimvera/java-standard-edition/src/d0ae9863354c48291cc4ff0e91e9f80fd96fdce2/src/main/java/io/shido/patterns/Singleton.java?at=master)...although your class looks like a normal class – x80486 Jun 19 '15 at 14:38
  • Please refer to this: [post](http://stackoverflow.com/a/2912312/2928710) – Yuri Jun 19 '15 at 14:42
  • 1
    Actually "implement singletons with enums" approach came from Joshua Bloch's [Effective Java Reloaded talk](https://sites.google.com/site/io/effective-java-reloaded) at Google I/O 2008. For sure, you will find there not only "how?" but "why?" too. – Vitalii Elenhaupt Jun 19 '15 at 15:10

3 Answers3

13

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
slartidan
  • 20,403
  • 15
  • 83
  • 131
  • I do not really understand why it should be a problem if I run my code several times in one VM? Could you explain a little bit more, please. – gabriel Aug 23 '17 at 13:14
  • Sure, but what do you actually mean by "run your code several times in one vm"? – gabriel Aug 23 '17 at 15:22
  • 1
    @gabriel Let's say you write a simple tetris game. One game field, it uses "W,A,S,D" keys as input. Now you decide, that you want to make it multi-player - with two game fields, one user uses "W,A,S,D", the other user "I,J,K,L". If your code has used a lot of "static" variables, it will be hard to "let it run twice" (once for each player). Reusing the code is much easier, if you avoided static variables. – slartidan Aug 24 '17 at 07:48
  • Ok, now I know what you meant! Thanks for your explanation! – gabriel Aug 24 '17 at 08:00
  • this is NOT how you do singleton initialization via enum! – Enerccio May 07 '19 at 08:58
  • @Enerccio Why is it not the right way to do it, in your opinion? – slartidan May 07 '19 at 18:02
3

Your "Employee" class isn't really something that should be a singleton, but here goes.

public enum Employee { 
   INSTANCE;

   private int id; 
   private String name; 

   private Employee() {}  //enum constructor must be private

   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; 
   }
}

Then you can do

Employee.INSTANCE.setName("Hello World!");
EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428
0

(Whether or not the singleton pattern is a good fit for your example use is discussed in other answers and comments. I will pretend to answer the specific question, even though it may not actually be relevant.)

Bloch's Effective Java has a nice discussion of this. See pp 17-18. I'm cribbing directly from this reference!

Basically, you can enforce the singleton pattern with an enum or a private constructor. Bloch prefers the former, even though it is a less common pattern.

e.g.:

// Enum singleton
public enum Elvis {
    INSTANCE;
    public void leaveTheBuilding() { ... }
}

Functionality equivalent to a public field approach, and is ready for serialization without any more boilerplate. And there will only ever be a single instance, even in the face of tricksy reflection or serialization access.