Wednesday, 17 August 2016

Why enum is the best approach to implement a Singleton class ?

In my previous blog (Implement SIngleton class in an efficient way), we have already discussed about all the approaches to implement a singleton class and concluded with the enum type implementation. As mentioned earlier enum is completely safe from reflection and serialization attack.

Now we will see in details that,
- Is enum really safe
- Whether we can break an enum from singleton with either reflection or serialization.

Before proceeding to this let's know more about enum in depth.

OK, what you think about this simple enum ? What is exactly an enum ?

Well, an enum is a simple class which extends java.lang.Enum class. Believe me this is the truth behind enum keyword. Java compiler plays the main role here while compiling the enum; it converts the enum to a normal class and extends that class directly from Enum class rather than Object class. Now let's check the truth.

So, the compiler injects 3 more elements (2 methods and 1 static block).

Let's try to instantiate an enum using java Reflection API.

Test class
Here the exception is because of private constructor. Since public/protected constructors are not allowed inside an enum, the default access scope of a constructor is private inside an enum. So it fails to instantiate directly.
Let's try by modifying the access scope of constructor.

Now this time the exception is because, inside java.lang.reflect.Constructor.newInstance(Object ... initargs), there is a condition check like below :

 So there is no way to instantiate an enum using reflection.

Let's try to make copy of an enum instance.
Test class
Now you can observe few things:
- hash code f both the objects are same
- state of the object got changed after it being serialized, but the changes are reflected in the deserialized object. So it is clear that the state of an enum instance is not serialized but the name by calling And while deserializing it gets only the name of the instance and by calling java.lang.Enum.valueOf() method it gets the actual enum instace.

Conclusion : enum type is a special class which can not be instantiated outside of the enum class in all possible way.

Please feel free to give your comment/suggestion. Thank you.

No comments:

Post a Comment