Enum in Java. Advantages

What is the advantage of using enum in java?

Advantages -

  • Set of Constant declaration
  • Restrict input parameter in method
  • Can be usable in switch-case

It is used for fields consist of a fixed set of constants.

Example is Thread.State

public enum State {
NEW,
RUNNABLE,
WAITING,
BLOCKED,
...
}

or private enum Alignment { LEFT, RIGHT };

You can restrict input parameter using Enum like-

String drawCellValue (int maxCellLnghth, String cellVal, Alignment align){}

Here in align parameter could be only Alignment.LEFT or Alignment.RIGHT which is restricted.

Example of switch-case with enum -

String drawCellValue (int maxCellLnghth, String cellVal, Alignment align){
switch (align) {
case LEFT:...
case RIGHT: ...
}
...
}

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 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's the advantage of a Java enum versus a class with public static final fields?

Technically one could indeed view enums as a class with a bunch of typed constants, and this is in fact how enum constants are implemented internally. Using an enum however gives you useful methods (Enum javadoc) that you would otherwise have to implement yourself, such as Enum.valueOf.

Benefits of using Enums over Collections

Indeed, a Set<String> is more efficient in terms of performance when searching. However, I wouldn't expect that you have thousands of account types, but several, so you won't actually feel the difference when searching. There's one problem with this approach, though - you will be able to add any String to the Set, which is brittle.

My personal prefer would be to use an enum, especially if you don't expect that more account types will be introduced. And if you have a Set<AccountType> you'll be restricted with the values you can add (i.e. you will be able to add only account types, but not anything, like the approach with a Set<String>). The problem with this approach is the Open/Closed Principle - consider you have a switch statement over a AccountType variable with all the corresponding cases. Then, if you introduce a new AccountType constant, you must change the switch statement (with adding a new case), which breaks the "Open/Closed principle". In this case the neatest design would be to have an abstract class/interface, called AccountType which has all the specific account types as sub-classes.

So, there are several approaches you can follow, but before picking one, you should try answer yourselves the question of "How are we going to use it?"

Are there advantages to using an enum where you could use a map and vice versa?

Here are things I like to keep in mind:

Enums are best used (and in the languages I know of, may only be used) to define a known set of items ahead of time. This has a nice benefit of treating what really boils down to frequently used "data" as code in a very readable way.

In my opinion, any code that relies on frequently hardcoded strings, like you would need to use if implementing data like that in a map is more difficult to read and maintain. This leads to "magic strings", which is a no-no when avoidable.

It's not immediately clear what should exist in the map until you go check, and it's not clear if it's potentially being modified elsewhere. Consider, that if you got an enum value wrong, the code will not even compile. Get a string key wrong, and you might not notice until much later.

Regarding performance, I doubt there is a large difference between the two. Enums are treated largely the same as objects, I suppose the benefit comes from accessing the data as a field on the object rather than a hash lookup.

This article doesn't go in depth as I would like, but may be a good starting point: Memory Consumption of Java Data Types

It is quite common practice to use an enum as keys for a known map and that offers another way of associating data with a set of specific items (rather than setting them as fields on the enum). I believe this approach would be my preferred method since setting lots of fields on an enum makes them feel too much like a class rather than a method of referencing. This doesn't have the same problems as a normal map because since the keys must be enums you don't need to worry about any other keys "accidentally" being added to the map. It seems Java as a whole supports this approach as they provide the EnumMap class.

What's the benefit of using enum embedded inside a class in JAVA?

The advantage of using an enum is that it is the clearest and most type-safe way of expressing the programmer's intent. In this case ... it is declaring a set of 5 named "colour" values in a way that prevents them from being confused with any other values in your Java program.

The advantage of embedding the enum cannot be discerned from this highly artificial example, but it is typically that the embedded class / enum has a close semantic relationship to the enclosing class.

What is the pros and cons between Enum and enum-based class implementation in Java?

In Java, Enum types act as a class that is declared with their unique name. It is pretty much like the any other class that is designed to create constant values. Recently, I also came across to an info that before the declaration of Enums in Java, an enum like class was created. Just like the article that was suggested on this question, it seems that previous to JVM 1.5, class based enums were widely used.

You can check this source: http://javarevisited.blogspot.com/2011/08/enum-in-java-example-tutorial.html

I think it is a very good explanation on Java Enums and Why they are created. The article claims 3 advantages for Enum:

1)Type Safety.

2)Unless the class was worked thoroughly, the Enum class was prone to printing problems. When coder wanted a string result to be returned, an primitive value was returned. To my experience, with some additions to the class, this is avoided. But question is, is it convenient for the coder.

3)Again, access was based on an instance of the class. Thus, coder cannot access to the Enum option directly. Coder must use the class name.

As a result: for convenience and code readability issues, Enums are a good choice. Plus, Enum Structure is similar to an individual classes that are nested within a carrier class. If coder wants to enhance the Enum Design and create their own style, they can turn back to the old manually coded class based system.

Understanding Enums in Java

Enums in Java 5+ are basically classes that have a predefined set of instances. They are intended as a replacement for, say, a collection of integer constants. They are preferably to constants as they can enforce type safety.

So instead of:

public class Suit {
public final static int SPADES = 1;
public final static int CLUBS = 2
public final static int HEARTS = 3;
public final static int DIAMONDS = 4;
}

you have:

public enum Suit {
SPADES, CLUBS, HEARTS, DIAMONDS
}

The advantages are:

  1. Type safety. You can declare a function argument, return type, class member or local variable to be a particular Enum type and the compiler will enforce type safety;
  2. Enums are basically classes. They can implement interfaces, have behaviour and so on.

The type safety is an issue because in the first example, these are valid statements:

int i = Suit.DIAMONDS * Suit.CLUBS;

or you can pass in 11 to a function expecting a suit. You can't do that with a typesafe enum.

You can use a class for Suit to provide type safety and this was the solution before Java 5. Josh Bloch (in Effective Java, which is a must read for Java programmers imho) promoted the typesafe enum pattern that became the Java 5+ enum. It has a fair amount of boilerplate on it and some corner cases that people didn't tend to cater for, such as serialization not calling a constructor and to ensure you only got one instance you had to override the readResolve() method.

For example:

public enum CardColour {
RED, BLACK
}

public enum Suit {
SPADES(CardColour.BLACK),
CLUBS(CardColour.BLACK),
HEARTS(CardColour.RED),
DIAMONDS(CardColour.RED);

private final CardColour colour;

Suit(CardColour colour) { this.colour = colour; }

public CardColour getColour() { return colour; }
}

Edit: Sun has an introduction to typesafe enums.

As for interfaces, they really complement enums rather than being an alternative. Like you could say that Suit is an interface and you'd have this:

public interface Suit {
CardColour getColour();
}

The problem is that you could go and define 300 different suits and you could also define Spades several times. Another advantage of enums is (classloading corner cases notwithstanding) is that there is only one instance of each enum value. Typically this is referred to as having a canonical value, meaning this equality holds true:

a.equals(b) == b.equals(a) == (a == b)

for all a, b that are instances of a particular Enum. This means that instead of writing:

if (card.getSuit().equals(Suit.SPADES)) { ... }

you can write:

if (card.getSuit() == Suit.SPADES) { ... }

which is quicker and typically easier to read. Plus IDEs will typically give you feedback if you're comparing enums of different types saying they can't possibly be equal, which can be a useful and early form of error-checking.



Related Topics



Leave a reply



Submit