Java Enumeration

An enumeration in Java denotes a list of named constants. Enumeration has been added in Java since Java SE 5. It is also called an enum. Every constant in enum is public, static and final by default. Basically, it defines a class type in Java. An enum can have instance variables, constructors and methods. All enums implicitly extend java.lang.Enum class, so it can’t inherit any other class, but it can implement many interfaces. We can define it either inside the class or outside the class. The toString() method is overridden in Enum class, which returns enum constant name.

An enumeration (or enum) can be created using the enum keyword. To separate the constants we can use a comma symbol. Note that these constants should be in uppercase letters by convention. See the following example:

enum Card {
CLUB, DIAMOND, HEART, SPADE
}

Here, Card is an enum type denoting a deck of playing cards with four different suits named CLUB, DIAMOND, HEART and SPADE; each represents a named constant.

Note that the semicolon (;) at the end of the enum constants are optional. So, the above enum type definition is same as:

enum Card {
CLUB, DIAMOND, HEART, SPADE;
}

We can access the constants of enum with the dot operator:

Card card = Card.CLUB;

 

 

Enum toString() method

As already mentioned, an enum class automatically gets a toString() method in the compiled class. This method returns a string value of the name of the given enum instance. See the following example:

String str = Card.CLUB.toString();

 

 

Enum contains main() method

An enum may contain main() method from where we can call the constant value(s). See it below.

Card.java

public enum Card {
CLUB, DIAMOND, HEART, SPADE;

public static void main(String[] args) {
Card card = Card.CLUB;
System.out.println("Value: " + card);
}
}

Output:

Value: CLUB

NOTE: Don’t instantiate an enum using new, because enum contains private constructors only.

 

 

Enum inside the class or outside the class

We can define an enum either inside the class or outside the class. See the following examples.

I. Example of Enum inside the class:

Test.java

public class Test {
enum Cards {
CLUB, DIAMOND, HEART, SPADE;
}
public static void main(String[] args) {
Card card = Card.CLUB;
System.out.println("Value: " + card);
}
}

Output:

Value: CLUB

 

II. Example of Enum outside the class:

Test.java

enum Cards {
CLUB, DIAMOND, HEART, SPADE;
}

public class Test {
public static void main(String[] args) {
Card card = Card.CLUB;
System.out.println("Value: " + card);
}
}

Output:

Value: CLUB

 

 

Enum valueOf(), ordinal() and values() methods

  • The valueOf() method of Enum class returns the enum constant of the specified string value, if exists.
  • By using ordinal() method of Enum, each enum constant index can be found, such as array index.
  • The values() method in Enum can be used to return all values present inside enum.

See the following example of using a Java enum within the if..else…if ladder ladder. The program uses all the methods mentioned above.

EnumTest01.java

enum Card {
CLUB, DIAMOND, HEART, SPADE;
}

public class EnumTest01 {

public static void main(String[] args) {

Card card = Card.HEART; //refer to a constant

//if..else...if ladder
if(card==Card.CLUB)
System.out.println("Value: " + card);
else if(card==Card.DIAMOND)
System.out.println("Value: " + card);
else if(card==Card.HEART)
System.out.println("Value: " + card);
else
System.out.println("Value: " + card);

System.out.println(card + " is at index " + card.ordinal()); //2
System.out.println("Another Value: " + Card.valueOf("SPADE")); //1

//Enum Iteration
System.out.println("\nCard suits are:~");
System.out.println("================");
for (Card c : Card.values()) { //3
System.out.print(c + " ");
}
System.out.println();

}

}

Output:

Value: HEART
HEART is at index 2
Another Value: SPADE

Card suits are:~
================
CLUB DIAMOND HEART SPADE

 

 

Enum and Type Safety

The following example shows how enum provides type safety in Java. We are using the same enum Card here (mentioned in the previous example). Let us create a class with similar list of integer constants named CardConstants. See the program below.

Test.java

enum Card {
CLUB, DIAMOND, HEART, SPADE;
}

class CardConstants {
static final int CLUB = 1;
static final int DIAMOND = 2;
static final int HEART = 3;
static final int SPADE = 4;
}

public class Test {

public static void main(String[] args) {

//Enum values are fixed
System.out.println("Testing enum Card..");
testEnum(Card.HEART);
testEnum(null);

System.out.println("\nTesting class CardConstants..");
testClass(3);
//any int constant can be passed
testClass(7);
}

private static void testEnum(Cards c) {
if (c == Card.CLUB) {
System.out.println("CLUB");
} else if (c == Card.DIAMOND) {
System.out.println("DIAMOND");
} else if (c == Card.HEART) {
System.out.println("HEART");
} else {
System.out.println("SPADE");
}
}

private static void testClass(int c) {
if (c == CardConstants.CLUB) {
System.out.println("CLUB");
} else if (c == CardConstants.DIAMOND) {
System.out.println("DIAMOND");
} else if (c == CardConstants.HEART) {
System.out.println("HEART");
} else {
System.out.println("SPADE");
}
}
}

Output:

Testing enum Card..
HEART
SPADE

Testing class CardsConstant..
HEART
SPADE

If we look at the preceding example, we have two risks associated with the class of constants that are solved by the enum.

  1. We can pass any int constant to the testClass() method but we can pass only fixed values to testEnum() so it provides type safety.
  2. We can change the int constants value in CardConstants class but our program will not throw any exception. The program might not work as expected but if we change the enum constants, we will get compile time error that eliminates any possibility of runtime error.

So, It is evident from the above example that enum provides type safety.

 

 

Enum in switch-case statements

We can use enum in switch-case statements as shown in the example below:

EnumTest02.java

import java.util.Scanner;

enum Month {
JANUARY, FEBRUARY, MARCH,
APRIL, MAY, JUNE,
JULY, AUGUST, SEPTEMBER,
OCTOBER, NOVEMBER, DECEMBER;
}

public class EnumTest02 {

Month month;

// Constructor of class EnumTest02
public EnumTest02(Month month) {
this.month = month;
}

// To know the season of the month using switch-case
public void knowTheSeason() {
System.out.println("\nknowTheSeason() method called..");
switch (month) {
case JANUARY:
case FEBRUARY:
System.out.println(month + " month belongs to Winter Season");
break;

case MARCH:
case APRIL:
System.out.println(month + " month belongs to Spring Season");
break;

case MAY:
case JUNE:
System.out.println(month + " month belongs to Summer Season");
break;

case JULY:
case AUGUST:
System.out.println(month + " month belongs to Rainy Season");
break;

case SEPTEMBER:
case OCTOBER:
System.out.println(month + " month belongs to Autumn Season");
break;

default:
System.out.println(month + " month belongs to Pre-Winter Season");
break;
}
}

public static void main(String[] args) {

Scanner sc = new Scanner(System.in);

System.out.println("\Months in a calendar year are:~");
System.out.println("=================================");
for (Month m : Month.values()) {
System.out.print(m + " ");
}
System.out.println();

System.out.println("\nEnter the month name (in caps): ");
String str = sc.next();
EnumTest02 et = new EnumTest02(Month.valueOf(str));
et.knowTheSeason();
}
}

 

Output:

Months in a calendar year are:~
=================================
JANUARY FEBRUARY MARCH APRIL MAY JUNE JULY AUGUST SEPTEMBER OCTOBER NOVEMBER DECEMBER

Enter the month name (in caps):
JUNE

knowTheSeason() method called..
JUNE month belongs to Summer Season

 

 

Enum with constructor, field and method

The following example creates an enum type named Month with constructor, field and method. See the program code below.

EnumTest03.java

enum Month {

JANUARY(1), FEBRUARY(2), MARCH(3),
APRIL(4), MAY(5), JUNE(6),
JULY(7), AUGUST(8), SEPTEMBER(9),
OCTOBER(10), NOVEMBER(11), DECEMBER(12);

private int number; // number of each month

// Constructor of enum Months
Month(int n) {
number = n;
}

// Returns the number of month
int getNumber() {
return number;
}

}

public class EnumTest03 {

public static void main(String[] args) {
System.out.println("All months in a year:~");
System.out.println("======================");
for (Month m : Month.values()) {
System.out.println(m + " is number " + m.getNumber() + " month.");
}
}
}

Output:

All months in a year:~
======================
JANUARY is number 1 month.
FEBRUARY is number 2 month.
MARCH is number 3 month.
APRIL is number 4 month.
MAY is number 5 month.
JUNE is number 6 month.
JULY is number 7 month.
AUGUST is number 8 month.
SEPTEMBER is number 9 month.
OCTOBER is number 10 month.
NOVEMBER is number 11 month.
DECEMBER is number 12 month.

 

 

Enum and abstract methods

An enum can have abstract methods. Then, we must implement these methods in each instance of the enum. See the code snippet below.

enum Direction {

NORTH {
@Override
public String getInfo() {
return NORTH.toString().toLowerCase();
}
},
SOUTH {
@Override
public String getInfo() {
return SOUTH.toString().toLowerCase();
}
},
EAST {
@Override
public String getInfo() {
return EAST.toString().toLowerCase();
}
},
WEST {
@Override
public String getInfo() {
return WEST.toString().toLowerCase();
}
};

public abstract String getInfo();
}

 

 

EnumSet and EnumMap Example

The following example shows the uses of java.util.EnumSet and java.util.EnumMap classes with program code:

Testing.java

import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Iterator;

enum Direction {
NORTH, SOUTH, EAST, WEST;
}

public class Testing {

public static void main(String[] args) {

//EnumSet Example
EnumSet<Direction> enumSet = EnumSet.of(Direction.NORTH, Direction.SOUTH);
Iterator<Direction> it = enumSet.iterator();
while (it.hasNext()) {
System.out.println(it.next());;
}

//EnumMap Example
EnumMap<Direction, String> enumMap = new EnumMap<Direction, String>(Direction.class);
enumMap.put(Direction.NORTH, "1");
enumMap.put(Direction.SOUTH, "2");
enumMap.put(Direction.EAST, "3");
enumMap.put(Direction.WEST, "4");

String direction = enumMap.get(Direction.EAST);
System.out.println(direction);
}
}

 

Output:

NORTH
SOUTH
3

NOTE: One must have the concept of Collection and Generics to understand this example.