Today I was browsing through some questions on this site and I found a mention of an enum
being used in singleton pattern about purported thread safety benefits
In addition to @BradB Answer :
That is so true... It's strange that it is the only answer who mention that. When beginners discover enums, they quickly take that as a magic-trick for valid identifier checking for the compiler. And when the code is intended to be use on distributed systems, they cry... some month later. Maintain backward compatibility with enums that contains non static list of values is a real concern, and pain. This is because when you add a value to an existing enum, its type change (despite the name does not).
"Ho, wait, it may look like the same type, right? After all, they’re enums with the same name – and aren’t enums just integers under the hood?" And for these reasons, your compiler will likely not flag the use of one definition of the type itself where it was expecting the other. But in fact, they are (in most important ways) different types. Most importantly, they have different data domains – values that are acceptable given the type. By adding a value, we’ve effectively changed the type of the enum and therefore break backward compatibility.
In conclusion : Use it when you want, but, please, check that the data domain used is a finite, already known, fixed set.
a modern look at an old problem
This approach implements the singleton by taking advantage of Java's guarantee that any enum value is instantiated only once in a Java program and enum provides implicit support for thread safety. Since Java enum values are globally accessible, so it can be used as the singleton.
public enum Singleton {
SINGLETON;
public void method() { }
}
How does this work? Well, the line two of the code may be considered to something like this:
public final static Singleton SINGLETON = new Singleton();
And we get good old early initialized singleton.
Remember that since this is an enum you can always access to instance via Singleton.INSTANCE
as well:
Singleton s = Singleton.INSTANCE;
Advantages
valueOf
method is used with the deserialized name to get the desired instance. Enum
class. The reason that reflection cannot be used to instantiate objects of enum type is because the java specification disallows and that rule is coded in the implementation of the newInstance
method of the Constructor
class, which is usually used for creating objects via reflection:if ((clazz.getModifiers() & Modifier.ENUM) != 0)
throw new IllegalArgumentException("Cannot reflectively create enum objects");
map
. Rather than having a single instance per application (e.g. the java.lang.Runtime
) the multiton pattern instead ensures a single instance per key.Detailed description each of them is too verbose so I just put a link to a good article - All you want to know about Singleton
Enums are like classes. Like class, it also has methods and attributes.
Differences with class are: 1. enum constants are public, static , final. 2. an enum can't be used to create an object and it can't extend other classes. But it can implement interfaces.
ENum stands for "Enumerated Type". It is a data type having a fixed set of constants which you define yourself.
It is useful to know that enums
are just like the other classes with Constant
fields and a private constructor
.
For example,
public enum Weekday
{
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
The compiler compiles it as follows;
class Weekday extends Enum
{
public static final Weekday MONDAY = new Weekday( "MONDAY", 0 );
public static final Weekday TUESDAY = new Weekday( "TUESDAY ", 1 );
public static final Weekday WEDNESDAY= new Weekday( "WEDNESDAY", 2 );
public static final Weekday THURSDAY= new Weekday( "THURSDAY", 3 );
public static final Weekday FRIDAY= new Weekday( "FRIDAY", 4 );
public static final Weekday SATURDAY= new Weekday( "SATURDAY", 5 );
public static final Weekday SUNDAY= new Weekday( "SUNDAY", 6 );
private Weekday( String s, int i )
{
super( s, i );
}
// other methods...
}
Instead of making a bunch of const int declarations
You can group them all in 1 enum
So its all organized by the common group they belong to