Using Java Enums
See Java enums in action and learn their best practices
Join the DZone community and get the full member experience.
Join For FreeIn 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 lists of predefined constants.
In this article, I’ll discuss how to define and use enum types. I’ll 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:
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 of running the test in IntelliJ is:
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 of running the test in IntelliJ is:
Enums in If-Else if Statements
Often, you may need 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:
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 of running the test in IntelliJ is:
Enums in Switch Statements
To use enums in a switch statement, 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:
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 of running the test in IntelliJ is:
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 defined in the SimpleEnumExample class, , Days, 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:
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 of running the test in IntelliJ is:
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 follows:
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 of running the test in IntelliJ is:
Key Points
Some key points on the enum type are:
- Java enums extend the 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 a semicolon.
- You cannot create an instance of enum using the new operator.
- You can declare abstract methods within an enum. If you do, all the enum fields must implement the abstract methods.
- You can use the “==” 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 inexperienced programmers who are not familiar with enums.
Enums remove “magic numbers,” 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 the method takes as inputs, you should ideally use enums. This is what is called type safety. Enums let you control the required set of inputs.
Published at DZone with permission of John Thompson, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments