Using Java Enums
0 CommentsLast Updated on June 5, 2019 by Michelle Mesiona
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.
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.
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.
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.
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.
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.
Key Points
Some key points on enum
type are:
- Java
enum
extendsjava.lang.Enum
class implicitly. Therefore, you cannot extend any other class inenum
. - Enums can implement interfaces. They implicitly implement the
Serializable
andComparable
interfaces. This means if you need some common functionality along diverseenum
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 anenum
type. - In an
enum
definition, comma separated constants must be terminated with semicolon. - You cannot create an instance of
enum
using thenew
operator. - You can declare abstract methods within an
enum
. If you do so, all theenum
fields must implement the abstract methods. - You can use “==” operator to compare
enum
constants effectively, sinceenum
constants arefinal
.
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.