Monday, 17 November 2014

Enums in Java

Hi Guys ,


As i was exploring enums in java , will share the following useful info regarding enums..

Java enums are a special Java type used to define collections of constants. An enum type is a special kind of Java class. It can contain constants, methods etc.


Enum Example

Here is a simple enum definition:

public enum Level {
    HIGH,
    MEDIUM,
    LOW
}You can refer to the constants in the above enum like this:
Level level = Level.HIGH;
Notice how the level variable is of the type Level which is the enum type from the example above. The levelvariable can take one of the Level enum constants as value (HIGHMEDIUM or LOW). In this case level is set toHIGH.

Enums in if Statements

Being constants, you will often have to compare a variable pointing to an enum constant against the possible constants in the enum type. Here is how that could look:
Level level = ...  //assign some Level constant to it

if( level == Level.HIGH) {

} else if( level == Level.MEDIUM) {

} else if( level == Level.LOW) {

}
This code compares the level variable against each of the possible enum constants in the Level enum.
If one of the enum values occur more often than the others, checking for that value in the first if-statement will result in better performance, as less comparison on average are executed. This is not a big difference though, unless the comparisons are executed a lot.

Enums in switch Statements

If your enum types contain a lot constants and you need to check a variable against the values as shown in the previous section, using a switch statement might be a good idea.
You can use enums in switch statements like this:
Level level = ...  //assign some Level constant to it

switch (level) {
    case HIGH   : ...; break;
    case MEDIUM : ...; break;
    case LOW    : ...; break;
}
Replace the ... with the code to execute if the level variable matches the given Level constant value. The code could be a simple Java operation, a method call etc.

Enum Iteration

You can obtain an array of all the possible values of an enum type by calling its static values() method. All enum types get a static values() method automatically by the Java compiler. Here is an example:
for (Level level : Level.values()) {
    System.out.println(level);
}
Running this code would print out all the enum values. Here is the output:
HIGH
MEDIUM
LOW
Notice how the names of the constants themselves are printed out.

Enum Fields

You can add fields to an enum. Thus, each constant value gets these fields. The field values must be supplied to the constructor of the enum when defining the constants. Here is an example:
public enum Level {
    HIGH  (3),  //calls constructor with value 3
    MEDIUM(2),  //calls constructor with value 2
    LOW   (1)   //calls constructor with value 1
    ; // semicolon needed when fields / methods follow


    private final int levelCode;

    public Level(int levelCode) {
        this.levelCode = levelCode;
    }
}

Enum Methods

You can add methods to an enum too. Here is an example:
public enum Level {
    HIGH  (3),  //calls constructor with value 3
    MEDIUM(2),  //calls constructor with value 2
    LOW   (1)   //calls constructor with value 1
    ; // semicolon needed when fields / methods follow


    private final int levelCode;

    Level(int levelCode) {
        this.levelCode = levelCode;
    }
    
        public int getLevelCode() {
        return this.levelCode;
        }
    
}
You call en enum method via a reference to one of the constant values. Here is an example:
Level level = Level.HIGH;

System.out.println(level.getLevelCode());
This code would print out the value 3 which is the value of the levelCode field for the constant HIGH.
You are not restricted to simple getter and setter methods. You can also create methods that make calculations based on the field values of the enum constant. If your fields are not declared final you can even modify the values of the fields (although that may not be so good an idea, considering that the enums are supposed to be constants).

Enum Miscellaneous Details

Enums extend the java.lang.Enum class implicitly, so your enum types cannot extend another class.
when an enum contain fields and methods, the definition of fields and methods must always come after the list of constants in the enum. Additionally, the list of constants must be terminated by a semicolon;

A very basic enum declaration

enum can be declared using following syntax.
1
2
3
4
5
access-modifier enum enum-name
 {
     enum_type_1,
         enum_type_2      //(optioanl semi colon)
 }
Lets see some examples:
1
2
3
4
5
6
7
8
9
10
11
12
enum Direction {
     EAST,
     WEST,
     NORTH,
     SOUTH
 }
public enum Direction {
     EAST,
     WEST,
     NORTH,
     SOUTH;
 }

enum declaration inside a class

When declared inside a class, enums are always static by default and can be accessed as OutClassRef.EnumType.EnumVar.
1
2
3
4
5
6
7
8
9
10
public class TestOuter
 {
     enum Direction
     {
         EAST,
         WEST,
         NORTH,
         SOUTH
     }
 }
Like for above enum, if declared inside TestOuter.java, we can access a direction using TestOuter.Direction.NORTH.

How enum constructors can be used

By default, enums do not require you to give constructor definitions and their default values is always represented by string used in declaration.
Though, you can give define your own constructors to initialize the state of enum types.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
enum Direction {
    // Enum types
    EAST(0), WEST(180), NORTH(90), SOUTH(270);
 
    // Constructor
    private Direction(final int angle) {
        this.angle = angle;
    }
 
    // Internal state
    private int angle;
 
    public int getAngle() {
        return angle;
    }
}

Can we extend enum types?

NO, you can not. Enum types are final by default and hence can not be extended. Yet, you are free to implement any number of interfaces as you like.
How to use template methods in enum
Remember that the enum is basically a special class type, and can have methods and fields just like any other class. So, you can define a template for enum creation also. For example: If we want that each enum type of Direction should be able to shout the direction name, when needed. This can be done by defining a abstract method inside Direction, which each enum has to override.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package enumTest;
 
public enum Direction {
    // Enum types
    EAST(0) {
        <strong>@Override</strong>
        public void shout() {
            System.out.println("Direction is East !!!");
        }
    },
    WEST(180) {
        @Override
        public void shout() {
            System.out.println("Direction is West !!!");
        }
    },
    NORTH(90) {
        @Override
        public void shout() {
            System.out.println("Direction is North !!!");
        }
    },
    SOUTH(270) {
        @Override
        public void shout() {
            System.out.println("Direction is South !!!");
        }
    };
    // Constructor
    private Direction(final int angle) {
        this.angle = angle;
    }
 
    // Internal state
    private int angle;
 
    public int getAngle() {
        return angle;
    }
 
    <strong>// Abstract method which need to be implemented</strong>
    public abstract void shout();
}

Collecting key notes about enum

  • enums are implicitly final subclasses of java.lang.Enum
  • if an enum is a member of a class, it’s implicitly static
  • new can never be used with an enum, even within the enum type itself
  • name and valueOf simply use the text of the enum constants, while toString may be overridden to provide any content, if desired
  • for enum constants, equals and == amount to the same thing, and can be used interchangeably
  • enum constants are implicitly public static final
  • the order of appearance of enum constants is called their “natural order”, and defines the order used by other items as well : compareTo, iteration order of values , EnumSet, EnumSet.range.
  • Constructors for an enum type should be declared as private. The compiler allows non private declares for constructors, but this seems misleading to the reader, since new can never be used with enum types.
  • Since these enumeration instances are all effectively singletons, they can be compared for equality using identity (“==”).
  • you can use Enum in Java inside Switch statement like int or char primitive data type




No comments:

Post a Comment