What Are Enums and Why Are They Useful

What are enums and why are they useful?

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?

/** Counts number of foobangs.
* @param type Type of foobangs to count. Can be 1=green foobangs,
* 2=wrinkled foobangs, 3=sweet foobangs, 0=all types.
* @return number of foobangs of type
*/
public int countFoobangs(int type)

versus

/** Types of foobangs. */
public enum FB_TYPE {
GREEN, WRINKLED, SWEET,
/** special type for all types combined */
ALL;
}

/** Counts number of foobangs.
* @param type Type of foobangs to count
* @return number of foobangs of type
*/
public int countFoobangs(FB_TYPE type)

A method call like:

int sweetFoobangCount = countFoobangs(3);

then becomes:

int sweetFoobangCount = countFoobangs(FB_TYPE.SWEET);

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.
Also, an invalid call like

int sweetFoobangCount = countFoobangs(99);

is no longer possible.

What is the point of enums?

The entire point of enums are to make your code more readable. They are not casted to ints, since they are by default ints. The only difference is instead of going back and forth checking what int values you may have, you can have a clear set of enums to make the code more readable.

Why use Enums instead of Constants? Which is better in terms of software design and readability

Suppose you use constant strings (or int values - the same goes for them):

// Constants for player types
public static final String ARCHER = "Archer";
public static final String WARRIOR = "Warrior";

// Constants for genders
public static final String MALE = "Male";
public static final String FEMALE = "Female";

then you end up not really knowing the type of your data - leading to potentially incorrect code:

String playerType = Constants.MALE;

If you use enums, that would end up as:

// Compile-time error - incompatible types!
PlayerType playerType = Gender.MALE;

Likewise, enums give a restricted set of values:

String playerType = "Fred"; // Hang on, that's not one we know about...

vs

PlayerType playerType = "Fred"; // Nope, that doesn't work. Bang!

Additionally, enums in Java can have more information associated with them, and can also have behaviour. Much better all round.

What's the use of enum in Java?

Enum serves as a type of fixed number of constants and can be used at least for two things

constant

public enum Month {
JANUARY, FEBRUARY, ...
}

This is much better than creating a bunch of integer constants.

creating a singleton

public enum Singleton {
INSTANCE

// init
};

You can do quite interesting things with enums, look at here

Also look at the official documentation

What is Enum useful for?

There are other things you can do and reasons to use them, but the primary reason I use enums is to prevent the possibility of an invalid parameter. For example, imagine the following method:

public void doSomethingWithAMonth(int monthNum);

This is not only ambiguous (do month indexes start at 1, or at 0?), but you can give down-right invalid data (13+, negative numbers). If you have an enum Month with JAN, FEB, etc. the signature becomes:

public void doSomethignWithAMonth(Month month);

Code calling this method will be far more readable, and can't provide invalid data.

When to use enums?

The concept behind an enum is also sometimes called an "enumerated type". That is to say, it's a type all of whose possible values are named and listed as part of the definition of the type.

C actually diverts from that a bit, since if a and b are values in an enum, then a|b is also a valid value of that type, regardless of whether it's listed and named or not. But you don't have to use that fact, you can use an enum just as an enumerated type.

They're appropriate whenever you want a variable whose possible values each represent one of a fixed list of things. They're also sometimes appropriate when you want to define a bunch of related compile-time constants, especially since in C (unlike C++), a const int is not a compile-time constant.

I think that their most useful properties are:

1) You can concisely define a set of distinct constants where you don't really care what the values are as long as they're different. typedef enum { red, green, blue } color; is better than:

#define red   0
#define green 1
#define blue 2

2) A programmer, on seeing a parameter / return value / variable of type color, knows what values are legal and what they mean (or anyway knows how to look that up). Better than making it an int but documenting "this parameter must be one of the color values defined in some header or other".

3) Your debugger, on seeing a variable of type color, may be able to do a reverse lookup, and give red as the value. Better than you looking that up yourself in the source.

4) The compiler, on seeing a switch of an expression of type color, might warn you if there's no default and any of the enumerated values is missing from the list of cases. That helps avoid errors when you're doing something different for each value of the enum.

What is the purpose of an Enum?

The purpose of using enums is to create a data type which will be represented as set of constant values like days of the week, months etc. also enums make Your code easier to read. An example of enums in C# is public enum Keys, if You want to check which key has been pressed by user it is easier to understand when You check it this way:

if (key == Keys.A)
{
//do something
}

instead of:

if (key == 65)
{
//do something
}

When I read the first code I immediately understand what it does, for the second one I would have to check which key has a value of 65.

Enum in Java. Advantages?

You get free compile time checking of valid values. Using

public static int OPTION_ONE = 0;
public static int OPTION_TWO = 1;

does not ensure

void selectOption(int option) {
...
}

will only accept 0 or 1 as a parameter value. Using an enum, that is guaranteed. Moreover, this leads to more self documenting code, because you can use code completion to see all enum values.

What is the use of enums in C and C++

Advantages over macros

  • Debuggers can print names for values
  • Your constants will be scoped (if you want, you can put them also in a namespace in C++)
  • The compiler can warn if you forget an enum constant in a switch
  • Values for the constants are automatically assigned, if you don't give explicit values
  • The enum type is always large enough to hold all the constants. When using #define, you have to commit to int or some typedef and ensure that all the constants fit manually

Why would enum be more useful than a HashMap in this situation?

Enum instances are objects, encapsulating data and behaviour just like any other object. By passing enum instances around, anyone can call its methods. If you pass Map keys as Strings, for example, you can't do anything useful with the key. Moreover, the code is less type-safe, and less self-documenting, since the String could very well be something completely different from what it's supposed to be.

What's the most readable?

public int countDays(Set<Month> months, int year) {
int count = 0;
for (Month month : months) {
count += month.getDays(year);
}
return count;
}

or

public int countDays(Set<String> months, int year) {
int count = 0;
for (String month : months) {
int days = monthMap.get(month);
if (month.equals(Months.FEBRUARY)) {
days = computeDaysInFebruary(year);
}
count += days;
}
return count;
}

What if I pass something other than a month name in the set?



Related Topics



Leave a reply



Submit