The road so far….

June 27, 2010

Enums are Not Singleton !!

Filed under: java — Tags: , — Rahul Sharma @ 9:57 pm

After going through  couple of  blogs on Enums and associated design patterns, I started testing Enums and their behaviour especially in relation to Singleton pattern.  So I implemented a simple Enum and started to test it.

public enum MyApplicationFactory {
   ModuleOne;
   void operate() {
     System.out.println("Working On it!! ");
   }
}

public class MyAppFactoryTests {
  @Test
   public void testOne() {
     System.out.println(MyApplicationFactory.ModuleOne);
     MyApplicationFactory.ModuleOne.operate();
  }
}

This test went fine, so I added one more constant “ModuleTwo ” to Enum and that also went fine. But the problem came when I implemented a constructor in the Enum.  So now my Enum looks like this :

public enum MyApplicationFactory {
  ModuleOne, ModuleTwo;
  MyApplicationFactory() {
     System.out.println("MyApplicationFactory instance created. ");
  }
  void operate() {
     System.out.println("Working On it!! ");
  }
}
public class MyAppFactoryTests {
 @Test
 public void testTwo() {
 System.out.println(MyApplicationFactory.ModuleOne);
 }
}

Now this test is not doing any thing but it highlights a point in relation to Enums instantiation. The test had the following output:

MyApplication instance created.
MyApplication instance created.
ModuleOne

If we look at the output it shows that the constructor is called twice before the Enum gets printed. This output made me feel that Enums are not really singleton and any implementation that relies on the singleton behavior of enum is bound to fail.

But why were there two constructor calls in the first place ?

If we implement a simple test we will see that each of the Enum constant is an instance of MyApplicationFactory class which extends from java.lang.Enum class.

@Test
 public void testThree() {
  System.out.println(MyApplicationFactory.ModuleOne.getClass());
  System.out.println(MyApplicationFactory.ModuleOne.getClass().getSuperclass());
 }

If we try to decomple the class file we get the following source code:

public final enum  class MyApplicationFactory extends Enum {
 public static final enum MyApplicationFactory ModuleOne;
 public static final enum MyApplicationFactory ModuleTwo;
 private static final MyApplicationFactory[] $VALUES;

 public static MyApplicationFactory[] values()
 public static MyApplicationFactory valueOf(String)
 private MyApplicationFactory (String, int)
 void operate()
 static
}

Thus each of the Enum constant is an instance of a Enum class rather than just a constant in the Enum class. But the constructor  for the Enum class is private and that of Enum base class is protected and can not be invoked from outside. As a result of this there are as many objects instances as the number of constants defined in the Enum.

This behaviour changes the way we look at the Enum for singleton implementations.  Let us say  the contructor of my MyAppFactory Enum loads the spring context for my application but this will be loaded as many number of times as there are constants defined which is not what I asked for.

Advertisements

3 Comments »

  1. Hey Rahul,
    Enums are singleton when you have one constant defined in your Enum i.e. you can’t have ModuleTwo , you will just have ModuleOne. Enum are classes so when you define any constant it becomes an instance of that Emum class i.e. in your example ModuleOne and ModuleTwo are two instance of the enum MyApplicationFactory. When people say that the best implementation of Singleton is with enum it is implict that
    Enum will have one constant. We can have discussion on this tomorrow.

    Thanks
    Shekhar

    Comment by whyjava — June 27, 2010 @ 10:19 pm

    • I would agree that keeping it to a single constant keeps them as singleton but the moment we add a second constant the singleton does not hold true. So why in the first place implement a singleton that will break the moment you try to add something ? In my opinion they are just too brittle, can break your singleton behaviour and should be avoided if you requre it. If you implement them in such a way you are bound to change the implementation quite soon because classes evolve with time and when they evolve they bring in things that are quite unwarranted in the first place.

      Comment by Rahul Sharma — June 27, 2010 @ 11:30 pm

  2. Enums are instance controlled classes, not plain singletons. Though you can use them as singleton.

    Comment by Vaibhav Raj — May 6, 2013 @ 10:23 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: