65
25
|
Today I was browsing through some question on this site and I found mention of enum being used in singleton pattern and that there are some thread safety benefits to such solution.
I never used enums and I have been programing in java for more than couple a years now. And apparently they changed a lot and now they even do full blown support of OOP within them selfs.
Now why and what for should I use enum in day to day programing? | ||||||||||||||||||||
|
89
+50
|
You should always use enums when a variable (especially a method parameter) can only take one out of a small set of possible values. Examples would be things like type constants (contract status: "permanent", "temp", "apprentice"), or flags ("execute now", "defer execution").
If you use enums instead of integers (or String codes), you increase compile-time checking and avoid errors from passing in invalid constants, and you document which values are legal to use.
BTW, overuse of enums might mean that your methods do too much (it's often better to have several separate methods, rather than one method that takes several flags which modify what it does), but if you have to use flags or type codes, enums are the way to go.
As an example, which is better?
versus
In the second example, it's immediately clear which types are allowed, docs and implementation cannot go out of sync, and the compiler can enforce this.
| ||||||||||||
|
18
|
Something none of the other answers have covered that make enums particularly powerful are the ability to have template methods. Methods can be part of the base enum and overridden by each type. And, with the behavior attached to the enum, it often eliminates the need for if-else constructs or switch statements as this blog post demonstrates - where
enum.method() does what originally would be executed inside the conditional. The same example also shows the use of static imports with enums as well producing much cleaner DSL like code.
Some other interesting qualities include the fact that enums provide implementation for
equals() ,toString() and hashCode() and implement Serializable and Comparable .
For a complete rundown of all that enums have to offer I highly recommend Bruce Eckel's Thinking in Java 4th edition which devotes an entire chapter to the topic. Particularly illuminating are the examples involving a Rock, Paper, Scissors (i.e. RoShamBo) game as enums.
| ||
11
|
From Java documents -
A common example is to replace a class with a set of private static final int constants (within reasonable number of constants) with an enum type. Basically if you think you know all possible values of "something" at compile time you can represent that as an enum type. Enums provide readability and flexibility over a class with constants.
Few other advantages that I can think of enum types. They is always one instance of a particular enum class (hence the concept of using enums as singleton arrives). Another advantage is you can use enums as a type in switch-case statement. Also you can use toString() on the enum to print them as readable strings.
| ||||||||||||
|
11
|
In his book Effective Java, Second Edition, Joshua Bloch elaborates on this approach in Item 3: Enforce the Singleton Property with a Private Constructor or an enum Type, reprinted in Dr. Dobb's.
| ||||
10
|
Besides the already mentioned use-cases, I often find enums useful for implementing the strategy pattern, following some basic OOP guidelines:
The simplest example would be a set of
Comparator implementations:
This "pattern" can be used in far more complex scenarios, making extensive use of all the goodies that come with the enum: iterating over the instances, relying on their implicit order, retrieving an instance by its name, static methods providing the right instance for specific contexts etc. And still you have this all hidden behind the interface so your code will work with custom implementations without modification in case you want something that's not available among the "default options".
I've seen this successfully applied for modeling the concept of time granularity (daily, weekly, etc.) where all the logic was encapsulated in an enum (choosing the right granularity for a given time range, specific behavior bound to each granularity as constant methods etc.). And still, the
Granularity as seen by the service layer was simply an interface. | ||
6
| Enum s enumerate a fixed set of values, in a self-documenting way.They make your code more explicit, and also less error-prone.
Why not using
String , or int , instead of Enum , for constants?
Moreover, each of the
Enum 's instances is a class, for which you can define its individual behaviour.
Plus, they assure thread safety upon creation of the instances (when the enum is loaded), which has seen great application in simplifying the Singleton Pattern.
This blog illustrates some of its applications, such as a State Machine for a parser.
| ||
5
|
Why use any programming language feature? The reason we have languages at all is for
Enums improve both liklihood of correctness and readability without writing a lot of boilerplate. If you are willing to write boilerplate, then you can "simulate" enums:
Now you can write:
The boilerplate above has much the same effect as
Both provide the same level of checking help from the compiler. Boilerplate is just more typing. But saving a lot of typing, makes the programmer more efficient (see 1), so it's a worthwhile feature.
It's worthwhile for at least one more reason, too:
Switch statements
One thing that the
static final enum simulation above does not give you is nice switch cases. For enum types, the Java switch uses the type of its variable to infer the scope of enum cases, so for theenum Color above you merely need to say:
Note it's not
Color.RED in the case. If you don't use enum, the only way to use named quantities work with switch is something like:
But now a variable to hold a color must have type
int . The nice compiler checking of the enum and thestatic final simulation is gone. Not happy.
Using an enum as a singleton
From the boilerplate above you can see why an enum provides a way to implement a singleton. Instead of writing:
and then accessing it with
we can just say
which gives us the same thing. We can get away with this because Java enums are implemented as full classes with only a little syntactic sugar sprinkled over the top. This is again less boilerplate, but it's non-obvious unless the idiom is familiar to you. I also dislike the fact that you get the various enum functions even though they don't make much sense for the singleton:
ord and values , etc. (There's actually a trickier simulation where Color extends Integer that will work with switch, but it's so tricky that it even more clearly shows why enum is a better idea.)
Thread safety
Thread safety is a potential problem only when singletons are created lazily with no locking.
If many threads call
getInstance simultaneously while INSTANCE is still null, any number of instances can be created. This is bad. The only solution is to add synchronized access to protect the variable INSTANCE .
However, the
static final code above does not have this problem. It creates the instance eagerly at class load time. Class loading is synchronized. So there is no problem.
The
enum singleton does not provide lazy creation either.
So the claim that enums are more thread safe than a manually created singleton is not exactly right. What can really be said is this: Singletons created at class load time (whether by enum or
static final initialization) are thread safe. Lazily created ones are not unless explicitly synchronized. | ||
4
|
Apart from all said by others.. In an older project that I used to work for, a lot of communication between entities(independent applications) was using integers which represented a small set. It was useful to declare the set as
enum with static methods to get enum object from value and viceversa. The code looked cleaner, switch case usability and easier writing to logs.
Create
enum object from received values (e.g. 1,2) using ProtocolType.fromInt(2) Write to logs using myEnumObj.name
Hope this helps.
| ||
3
|
In my opinion, all the answers you got up to now are valid, but in my experience, I would express it in a few words:
Use enums if you want the compiler to check the validity of the value of an identifier.
Otherwise, you can use strings as you always did (probably you defined some "conventions" for your application) and you will be very flexible... but you will not get 100% security against typos on your strings and you will realize them only in runtime.
| ||
3
|
After you define enum you get full power of following As it inherits all the methods of Object class and abstract class Enum.So,you can fully use its methods as per user requirement from reflection,multithreading,serilization,comparable and many.There are so many methods in abstract class Enum.So,you can see all possible methods there in abstract class Enum.If you just declare static constant in stead of enum ,you missed all above mentioned one.What methods to use it depends on urs design and implementation requirement.
public enum State { Start("1"), Wait("1"), Notify("2"), NotifyAll("3"), Run("4"), SystemInatilize("5"), VendorInatilize("6"), test, FrameworkInatilize("7"); public static State getState(String value) { return State.Wait; } private String value; State test; private State(String value) { this.value = value; } private State() { } public String getValue() { return value; } public void setCurrentState(State currentState) { test = currentState; } public boolean isNotify() { return this.equals(Notify); } }
I have written one program to demonstrate it ,hope it will help you to understand.Besides value of enum can be passed to dao layer as well.
| |||
2
|
ENum stands for "Enumerated Type". It is a data type having a fixed set of constants which you define yourself.
| ||||||||
|
2
| What is a enum:
Why to use enums:
Note:
|