Java enum, also called Java enumeration type, is a type whose fields consist of a fixed set of constants. The very purpose of an enum is to enforce compile-time type safety. The enum
keyword is one of the reserved keywords in Java.
We should use an enum when we know all possible values of a variable at compile time or design time, though we can add more values in the future as and when we identify them. In this java enum tutorial, we will learn what enums are and what problems they solve.
1. Enum Basics
Enumerations (in general) are generally a set of related constants. They have been in other programming languages like C++ from the beginning. After JDK 1.4, Java designers decided to support it in Java also, and it was officially released in JDK 1.5 release.
The enumeration in Java is supported by keyword enum
. The enums are a special type of class that always extends java.lang.Enum.
1.1. The enum is a Reserved Keyword
The enum is a reserved keyword which means we cannot define a variable with the name enum
. e.g. It will result in compile time error "invalid VariableDeclaratorId"
.
String enum = "Hello World !!";

1.2. Syntax to Create Enums
As we know, generally we deal with four directions in daily life. Their names, angles and other properties are fixed. So, in programs, we can create an enum for them. The syntax to create an enum is as below:
enum Direction {
EAST, WEST, NORTH, SOUTH;
}
Logically, each enum is an instance of enum type itself. So given enum can be seen as the below declaration. JVM internally adds ordinal and value methods to this class which we can call while working with an enum.
final class Direction extends Enum<Direction> {
public final static Direction EAST = new Direction();
public final static Direction WEST = new Direction();
public final static Direction NORTH = new Direction();
public final static Direction SOUTH = new Direction();
}
1.3. Naming Conventions
By convention, enums are constants. In Java, constants are defined in all UPPER_CASE letters. This follows for enums also.
- Enum name should be in title case (same as class names).
- Enum fields should be in all UPPER CASE (same as static final constants).
1.4. Enum Variables
We can create a variable of specified enum type just like we use final
static
class fields.
Direction north = Direction.NORTH;
System.out.println(north); //Prints NORTH
2. Enum Constructors
By default, enums don’t require constructor definitions and their default values are always the string used in the declaration. Though, you can give define your own constructors to initialize the state of enum types.
For example, we can add angle
attribute to direction. All directions have some angle.
enum Direction {
EAST(0), WEST(180), NORTH(90), SOUTH(270);
// constructor
private Direction(final int angle) {
this.angle = angle;
}
// internal state
private int angle;
public int getAngle() {
return angle;
}
}
If we want to access the angle for any direction, we can make a simple method call in the enum field reference.
Direction west = Direction.WEST;
System.out.println(west);
System.out.println(west.getAngle());
//or
System.out.println(Direction.WEST.getAngle());
Program output:
WEST
180
180
3. Inbuilt Methods
By default, an enum will have the following methods to access its constants.
3.1. ordinal()
The ordinal()
method returns the order of an enum instance among the list of constants. It represents the sequence in the enum declaration, where the initial constant is assigned an ordinal of '0'
. It is very much like array indices.
Ordinal is designed for use by sophisticated enum-based data structures, such as EnumSet
and EnumMap
.
Direction.EAST.ordinal(); //0
Direction.NORTH.ordinal(); //2
3.2. values() and valueOf()
The enum values() method returns all the enum values as an enum array.
Direction[] directions = Direction.values();
for (Direction d : directions) {
System.out.println(d);
}
The program output:
EAST
WEST
NORTH
SOUTH
The enum valueOf() method helps to convert a string to an enum instance.
Direction east = Direction.valueOf("EAST");
System.out.println(east);
Program output:
EAST
4. Custom Methods
Remember that an enum is basically a special class type, and can have methods and fields just like any other class. We can add methods that are abstract as well as non-abstract methods. Both methods are allowed in the enum.
4.1. Non-abstract Methods
Adding a concrete method in an enum is similar to adding the same method in any other class. We can use any access specifier e.g. public
, private
or protected
. We can return values from enum methods or simply use them to perform internal logic.
public enum Direction {
EAST, WEST, NORTH, SOUTH;
protected String message() {
String message = "Moving in " + this + " direction";
return message;
}
}
We can call the message() method as a simple method call on an enum instance.
Direction.NORTH.message();
4.2. Abstract Methods
We can also add abstract methods in enums. In this case, we must implement the abstract method at each enum field, individually.
public enum Direction
{
EAST {
@Override
public String message() {
return "You are moving in east. You will face sun in morning time.";
}
},
WEST {
@Override
public String message() {
return "You are moving in west. You will face sun in evening time.";
}
},
NORTH {
@Override
public String message() {
return "You are moving in north. Sea behind.";
}
},
SOUTH {
@Override
public String message() {
return "You are moving in south. Sea ahead.";
}
};
public abstract String message();
}
Re-run the above example.
Direction.WEST.message(); //You are moving in west. You will face sun in evening time.
Direction.NORTH.message(); //You are moving in north. Sea behind.
We can enforce a contract for all enums to be created in this way. It can serve as a template for enum creation.
For example, If we want that each enum type of Direction
should be able to print the direction name with a custom message when needed. This can be done by defining a abstract
method inside Direction
, which each enum has to override.
5. Inheritance
As mentioned earlier, enum extends Enum class. The java.lang.Enum
is an abstract class. This is the common base class of all Java enumeration types.
public abstract class Enum<E extends Enum<E>> extends Object
implements Constable, Comparable<E>, Serializable {
//...
}
It means that all enums are comparable and serializable implicitly. Also, all enum types in Java are singleton by default.
As noted all enums extends java.lang.Enum
, so enum cannot extend any other class because Java does not support multiple inheritance this way. But enums can implement any number of interfaces.
6. Comparing Two Enums
All enums are by default comparable and singletons as well. It means you can compare them with equals()
method, even with "=="
operator.
Direction east = Direction.EAST;
Direction eastNew = Direction.valueOf("EAST");
System.out.println( east == eastNew ); //true
System.out.println( east.equals( eastNew ) ); //true
We can compare enum types using
'=='
operator orequals()
method, because enums are singlton and comparable by default.
7. EnumSet and EnumMap
Two classes have been added to java.util
package in support of enums – EnumSet
(a high-performance Set implementation for enums; all members of an enum set must be of the same enum type) and EnumMap
(a high-performance Map implementation for use with enum keys).
7.1. EnumSet
EnumSet class is a specialized Set
implementation for use with enum types. All of the elements in an enum set must come from a single enum type that is specified, explicitly or implicitly, when the set is created.
Set enumSet = EnumSet.of(Direction.EAST,
Direction.WEST,
Direction.NORTH,
Direction.SOUTH
);
Like most collection implementations EnumSet
is not synchronized. If multiple threads access an enum set concurrently, and at least one of the threads modifies the set, it should be synchronized externally.
Note that null
elements are not permitted in EnumSet. Also, these sets guarantee the ordering of the elements in the set based on their order in the enumeration constants is declared. Performance and memory benefits are very high in comparison to a regular set implementation.
7.2. EnumMap
EnumMap is a specialized Map
implementation for use with enum type keys. Also, all of the keys in an enum map must come from a single enum type that is specified, explicitly or implicitly, when the map is created.
Like EnumSet
, null
keys are not permitted and is not synchronized as well.
Map<Direction, Integer> enumMap = new EnumMap(Direction.class);
enumMap.put(Direction.EAST, Direction.EAST.getAngle());
enumMap.put(Direction.WEST, Direction.WEST.getAngle());
enumMap.put(Direction.NORTH, Direction.NORTH.getAngle());
enumMap.put(Direction.SOUTH, Direction.SOUTH.getAngle());
8. Summary
- Java enums are implicitly final subclasses of
java.lang.Enum
class - If an enum is a member of a class, it’s implicitly
static
- The new keyword can not be used to initialize an enum, even within the enum type itself
- The
name()
andvalueOf()
methods, use the text of the enum constants, whiletoString()
method may be overridden to provide any content if desired. - For enum constants, equals() and “==” evaluate the same result and can be used interchangeably.
- enum constants are implicitly
public static final
- The order of appearance of the list of enum constants is called their “natural order“, and defines the order used by other items as well :
compareTo()
method, iteration order of values inEnumSet
,EnumSet.range()
. - Enum constructors should be declared as
private
. The compiler allows non-private constructors, but this seems misleading to the reader since new can never be used with enum types. - Since these enumeration instances are all effectively singletons, they can be compared for equality using identity (
"=="
). - We can use an enum in switch statements like int or char primitive data type.
In this article, we explored the Java enum from the language basics to more advanced and interesting real-world use cases.
Happy Learning !!