1. Background on how enum came to be

Today we will explore another kind of data type in Java: enum. The name enum comes from the word enumeration. What is this data type and what's it for?

Sometimes a programmer needs to create a new data type, whose possible values are limited to a small fixed list.

For example, a DayOfTheWeek type can only take the values MONDAY, TUESDAY, WEDNESDAY, ... There are 7 values in total. Or a Month type can only take only the values JANUARY, FEBRUARY, MARCH, ... There are 12 values in total.

Of course, you use could numbers (the int type): 1 — Monday, 2 — Tuesday, etc. But someone might accidentally assign invalid values such as 8 or 0 to your variable.

You could easily have a situation where one programmer thinks the days of the week (or months of the year) are numbered starting from zero, while others expect their numbering to start from one, etc.

That's why Java introduced enum, a data type that consists of a finite set of values.


2. Declaring a type

Declaring a new enum data type looks like this:

enum TypeName
{
   VALUE1,
   VALUE2,
   VALUE3
}

Where TypeName is the name of the new type (class), and the possible values are separated by commas and wrapped in curly braces: Value1, Value2, Value3.

As an example, let's create our own DayOfTheWeek enum:

Code Note
enum Day
{
   MONDAY,
   TUESDAY,
   WEDNESDAY,
   THURSDAY,
   FRIDAY,
   SATURDAY,
   SUNDAY
}
New Day type

Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday

Here is how you assign a value to a variable of our new type:

Day day = Day.MONDAY;

Example:

Code Note
Day day = Day.FRIDAY;
System.out.println(day);
The screen output will be:
FRIDAY


3. Methods of an enum

An enum type has several built-in methods, two of which are very interesting:

The static values() method returns an array of all of the values of the enum type:

Code Note
Day[] days = Day.values();

for (Day day: days)
   System.out.println(day);







System.out.println(days[2]);
The days variable stores an array containing the values of the Day type (7 elements)

Display the contents of the array on the screen:
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY

WEDNESDAY

The ordinal() method returns the ordinal number of the constant. You call it on an enum value rather than an enum class:

Code Console output
System.out.println(Day.MONDAY.ordinal());
System.out.println(Day.FRIDAY.ordinal());
System.out.println(Day.SUNDAY.ordinal());
0
4
6


4. Converting to a class

In reality, there's nothing magical here. The compiler just gave us some syntactic sugar. At compile time, the Day enum is converted to an ordinary class:

Code, simplified version Note
public class Day
{
   public static final Day MONDAY = new Day(0);
   public static final Day TUESDAY = new Day(1);
   public static final Day WEDNESDAY = new Day(2);
   public static final Day THURSDAY = new Day(3);
   public static final Day FRIDAY = new Day(4);
   public static final Day SATURDAY = new Day(5);
   public static final Day SUNDAY = new Day(6);

    private static final Day[] array = {MONDAY, TUESDAY,
      WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY};

   private final int value;

   private Day (int value)
   {
      this.value = value;
   }

   public int ordinal()
   {
      return this.value;
   }

   public static Day[] values()
   {
      return array;
   }
}
Day class

List of static constants







An array with all values of the Day enum


A variable that stores the value of a specific Day object

The Day class's constructor is private, which means objects of the Day class can only be created inside the Day class.



The ordinal method must be called on a Day object.

It returns the object's value — the value field.


The method returns a static array with all the values of the Day class

If we remove all static methods and variables from the Day class, we get the following:

Code Note
public class Day
{
  private int value;

  private Day (int value)
  {
    this.value = value;
  }

  public int ordinal()
  {
    return this.value;
  }
}


The value variable stores the value of the Day object

Day objects can only be created inside the Day class, since the constructor is private.




The ordinal() method returns the value of the Day object.

In other words, nothing scary is happening here. The compiler creates the Day class, adds the constants that represent the enum values, adds the necessary methods, and makes the class constructor private. We'll look at how constructors work a little later.

Hopefully, it is now clear why we assign a value to a variable in this way:

Day day = Day.MONDAY;

MONDAY is just a static field (constant) in the Day class. When accessing static methods and fields from outside the class, you must indicate the class name before the name of the field or method.



5. More methods of an enum

Every enum class has several interesting features.

Converting to and from a string

To convert an enum object to a string, you need to call its toString() method.

String str = Day.MONDAY.toString();

To convert in the other direction (from a string to a Day object), you can use the static valueOf() method:

Day day = Day.valueOf("MONDAY");

It is super convenient and will be helpful in many cases.

Converting to a number and back again

You already know how to convert an enum object to a number: call the ordinal() method:

int index = Day.MONDAY.ordinal();

To convert in the other direction (from a number to a Day object), you need a more transparent construct:

Day day = Day.values()[2];

Examples:

Code Note
Day day = Day.MONDAY;
int index = day.ordinal();
Day newDay = Day.values()[index+2];
Monday
Get the index of Monday: 0
Day of the week 2 days after Monday

Important point: because enum values are a fixed set of constants, they can be compared using ==. In other words, you can't have two identical MONDAY objects with different address. Only a single instance of each enum value exists. And that means that comparing enum variables using == will always work.



6. Adding your own methods to an enum

Because an enum turns into an ordinary class at compile time, you can declare methods in it. These methods are simply added to the class that the compiler generates. For example, suppose we want our Day enum to return a list of the enum values rather than an array.

Then we can add the following code:

Code Note
enum Day
{
   MONDAY,
   TUESDAY,
   WEDNESDAY,
   THURSDAY,
   FRIDAY,
   SATURDAY,
   SUNDAY;

   public static List<Day> asList()
   {
      ArrayList<Day> list = new ArrayList<Day>();

      Collections.addAll(list, values());

      return list;
   }

}








A semicolon is required after the list of values.



Create an ArrayList object

Add the values in the array returned by the values() method.
Return the list.

Now this method can be called in code:

Code Note
List<Day> list = Day.asList();
The list variable will store a list of all of the values of the Day enum.