Using Java Enums

Using Java Enums

0 Comments

In applications, you often need to work with a set of constant values. For example, representing a contract status with the “permanent”, “temp”, and “intern” values, or directions with the “north”, “south”, “east”, and “west” values.

In Java, you use the enum type (short for enumeration), a special datatype introduced in Java 5 to represent such list of predefined constants.

In this post, I’ll discuss how to define and use enum types. I will also include example code along with JUnit test cases. If you are new to JUnit, I suggest going through my JUnit series of posts.

Defining Java Enums

You can define an enum type either independently outside of any class or as part of a class. The code to define an enum independently is this.

package springframework.guru.enumexample;
enum Days{
   SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;
}

The preceding code defines an enum type, Days. The names of the enum type’s fields are in uppercase letters as they are constants.

Here is the JUnit test code.

package springframework.guru.enumexample;

import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class SimpleEnumExampleTest {
   @Test
   public void simpleEnumExampleOutsideClassTest(){
       Days day = Days.SUNDAY;
       System.out.println("Days enum is set a value: "+day);
       assertEquals(Days.valueOf("SUNDAY"), day);
   }
}

The test code assigns a value to the day variable of the enum type, Days. The day variable can take any of the seven defined values. In this case it is set to SUNDAY. The test code then asserts the value.

The output on running the test in IntelliJ is this.

SImple Java Enum Test Output

You can also define an enum inside a class, like this.

SimpleEnumExample.java

package springframework.guru.enumexample;

public class SimpleEnumExample {
   enum Days{
       SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;
   }
}

Here is the JUnit test code.

@Test
public void simpleEnumExampleInsideClassTest(){
   SimpleEnumExample.Days day = SimpleEnumExample.Days.SUNDAY;
   System.out.println("Days enum inside the class is set a value: "+day);
   assertEquals(SimpleEnumExample.Days.valueOf("SUNDAY"), day);
}

The output on running the test in IntelliJ is this.

Java enum test output

Enums in if-else if Statements

Often you may require to compare a variable pointing to an enum constant against all the possible values in the enum. This can be done with if-else if statements.

The code to use enums in an if-else if statement is this.

EnumInIfStatement.java

package springframework.guru.enumexample;

public class EnumInIfStatement {

   public String enumInIf(Days day) {
       if(day == Days.SUNDAY) {
           return "Its Sunday :-)";
       }else if (day == Days.MONDAY) {
           return "Its Monday :*--(";
       }else if (day == Days.TUESDAY) {
           return "Its Tuesday :*-(";
       }else if (day == Days.WEDNESDAY) {
           return "Its Wednesday :*(";
       }else if (day == Days.THURSDAY) {
           return "Its Thursday :)";
       }else if (day == Days.FRIDAY) {
           return "Its Friday ;-D";
       }else {
           return "Its Saturday :=D";
       }
   }
}

Here is the JUnit test code.

package springframework.guru.enumexample;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertEquals;

public class EnumInIfStatementTest {
   private EnumInIfStatement enumInIfStatement;

   @Before
   public void setUp() {
       enumInIfStatement = new EnumInIfStatement();
   }

   @After
   public void tearDown() {
       enumInIfStatement = null;
   }

   @Test
   public void enumInIfTest() {
       String result = enumInIfStatement.enumInIf(Days.SUNDAY);
       System.out.println(result);
       assertEquals("Its Sunday :-)", result);
   }
}

The output on running the test in IntelliJ is this.
Test Output of Java Enum in If Statemnent

Enums in Switch Statements

You can use enum in a switch statement. To do so, use the enum reference variable in the switch and enum constants or instances in case statements.

The code to use an enum type in a switch statement is this.

EnumInSwitchStatement.java

package springframework.guru.enumexample;

public class EnumInSwitchStatement {
   public String enumInSwitch(Days day) {
       switch(day) {
           case SUNDAY:
               return "Its Sunday!!";
           case MONDAY:
               return "Its Monday";
           case TUESDAY:
               return "Its Tuesday";
           case WEDNESDAY:
               return "Its Wednesday";
           default:
               return "Rest of the week....";
       }
   }
}

Here is the JUnit test code.

package springframework.guru.enumexample;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertEquals;

public class EnumInSwitchStatementTest {
   private EnumInSwitchStatement enumInSwitchStatement;

   @Before
   public void setUp() {
       enumInSwitchStatement = new EnumInSwitchStatement();
   }

   @After
   public void tearDown() {
       enumInSwitchStatement = null;
   }

   @Test
   public void enumInSwitchTest() {
       String result = enumInSwitchStatement.enumInSwitch(Days.SUNDAY);
       System.out.println(result);
       assertEquals("Its Sunday!!", result);
   }
}

The output on running the test in IntelliJ is this.
Test Output of Java Enum in Switch Statement

Enum Iteration

You can iterate through an enum to access its values. The static values() method of the java.lang.Enum class that all enums inherit gives you an array of enum values.

Let us use the same enum type, Days defined in the SimpleEnumExample class and iterate through its values.

EnumIteration.java

package springframework.guru.enumexample;

import java.util.ArrayList;

public class EnumIteration {
   enum Days{
       SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;
   }

   public ArrayList<String> enumIteration() {
       Days[] days = Days.values();
       ArrayList<String> stringDay = new ArrayList<String>();
       for (Days day : days) {
           stringDay.add(day.toString());
       }
       return stringDay;
   }
}

The test code is this.

package springframework.guru.enumexample;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Iterator;

import static org.junit.Assert.assertTrue;

public class EnumIterationTest {
   private EnumIteration enumIteration;

   @Before
   public void setUp() {
       enumIteration = new EnumIteration();
   }

   @After
   public void tearDown() {
       enumIteration = null;
   }

   @Test
   public void enumIterationTest() {
       ArrayList<String> result = enumIteration.enumIteration();
       Iterator iterator = result.iterator();
       while (iterator.hasNext()){
           System.out.println(iterator.next());
       }
       assertTrue(result.contains("SUNDAY"));
   }
}

The output on running the test in IntelliJ is this.
Test Output Enum Iteration

Enum Fields and Methods

Java enums can have fields and methods. You can add fields against each enum constant and the enum gets initialized with the values. When defining the constants, the enum constructor must be supplied with the values.

Note: If a Java enum contains fields and methods, the definition of fields and methods must always come after the list of constants in the enum.

The code to define an enum with fields, constructor, and methods is this.

EnumFields.java

package springframework.guru.enumexample;

import java.util.ArrayList;

enum AbbreviationOfDays{
   SUNDAY("SUN"), MONDAY("MON"), TUESDAY("TUES"), WEDNESDAY("WED"),
   THURSDAY("THURS"), FRIDAY("FRI"), SATURDAY("SAT");

   private String abbreviation;

   public String getAbbreviation() {
       return this.abbreviation;
   }

   AbbreviationOfDays(String abbreviation) {
           this.abbreviation = abbreviation;
   }
}
public class EnumFields {
   public ArrayList<String> enumFields() {
       AbbreviationOfDays[] abbreviationOfDays = AbbreviationOfDays.values();
       ArrayList<String> daysList = new ArrayList<String>();
       for (AbbreviationOfDays day : abbreviationOfDays) {
           daysList.add(day.getAbbreviation().toString());
       }
       return daysList;
   }
}

The AbbreviationOfDays enum has an abbreviation field of type String. The constructor takes a String abbreviation and assigns it to the field. The getAbbreviation() method returns the abbreviation field.

Note: You can also define methods that do some logical operations within an enum.

Here is the Junit test code.

package springframework.guru.enumexample;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Iterator;

import static org.junit.Assert.assertTrue;

public class EnumFieldsTest {
   private EnumFields enumFields;

   @Before
   public void setUp() {
       enumFields = new EnumFields();
   }

   @After
   public void tearDown() {
       enumFields = null;
   }

   @Test
   public void enumFieldsTest() {
       ArrayList<String> result = enumFields.enumFields();
       Iterator iterator = result.iterator();
       while (iterator.hasNext()){
           System.out.println(iterator.next());
       }
       assertTrue(result.contains("SUN"));
   }
}

The output on running the test in IntelliJ is this.
Test Output Java Enum Fields Methods

Key Points

Some key points on enum type are:

  • Java enum extends java.lang.Enum class implicitly. Therefore, you cannot extend any other class in enum.
  • Enums can implement interfaces. They implicitly implement the Serializable and Comparable interfaces. This means if you need some common functionality along diverse enum types. You can define it with an interface to have the enums provide the method implementations.
  • In Java, enum is a keyword.
    Enum constructors are always private or default. Therefore, you cannot have public or protected constructors in an enum type.
  • In an enum definition, comma separated constants must be terminated with semicolon.
  • You cannot create an instance of enum using the new operator.
  • You can declare abstract methods within an enum. If you do so, all the enum fields must implement the abstract methods.
  • You can use “==” operator to compare enum constants effectively, since enum constants are final.

Summary

I often see code with lots of int constants representing a set of predefined values instead of enums, which is a better fit. I attribute this to inexperience programmers who are not familar enums.

Enums remove “magic numbers”. These are numbers that don’t really mean anything on their own. By replacing those numbers with actual values, your code makes more sense and follows better coding principles.

Also, enums prevent incorrect values from being passed to a function. Consider that you have a method that takes an int value. This method will execute if we pass any int value. But if you want to restrict the values that the method takes as input, you should ideally use enums. This is what is called type safety. Enums lets you control the required set of inputs.

In enterprise application development with Spring, you will find enums defined in model classes. This is for applications that expects the users to provide the exact enums in the request which adds a validation for the incoming request.

About jt

    You May Also Like

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    This site uses Akismet to reduce spam. Learn how your comment data is processed.