Enum can be considered to be syntax sugar for a sealed class that is instantiated only a number of times known at compile-time to define a set of constants.
A simple enum to list the different seasons would be declared as follows:
public enum Season {
WINTER,
SPRING,
SUMMER,
FALL
}
While the enum constants don't necessarily need to be in all-caps, it is Java convention that names of constants are entirely uppercase, with words separated by underscores.
You can declare an Enum in its own file:
/**
* This enum is declared in the Season.java file.
*/
public enum Season {
WINTER,
SPRING,
SUMMER,
FALL
}
But you can also declare it inside another class:
public class Day {
private Season season;
public String getSeason() {
return season.name();
}
public void setSeason(String season) {
this.season = Season.valueOf(season);
}
/**
* This enum is declared inside the Day.java file and
* cannot be accessed outside because it's declared as private.
*/
private enum Season {
WINTER,
SPRING,
SUMMER,
FALL
}
}
Finally, you cannot declare an Enum inside a method body or constructor:
public class Day {
/**
* Constructor
*/
public Day() {
// Illegal. Compilation error
enum Season {
WINTER,
SPRING,
SUMMER,
FALL
}
}
public void aSimpleMethod() {
// Legal. You can declare a primitive (or an Object) inside a method. Compile!
int primitiveInt = 42;
// Illegal. Compilation error.
enum Season {
WINTER,
SPRING,
SUMMER,
FALL
}
Season season = Season.SPRING;
}
}
Duplicate enum constants are not allowed:
public enum Season {
WINTER,
WINTER, //Compile Time Error : Duplicate Constants
SPRING,
SUMMER,
FALL
}
Every constant of enum is public
, static
and final
by default. As every constant is static
, they can be accessed directly using the enum name.
Enum constants can be passed around as method parameters:
public static void display(Season s) {
System.out.println(s.name()); // name() is a built-in method that gets the exact name of the enum constant
}
display(Season.WINTER); // Prints out "WINTER"
You can get an array of the enum constants using the values()
method. The values are guaranteed to be in declaration order in the returned array:
Season[] seasons = Season.values();
Note: this method allocates a new array of values each time it is called.
To iterate over the enum constants:
public static void enumIterate() {
for (Season s : Season.values()) {
System.out.println(s.name());
}
}
You can use enums in a switch
statement:
public static void enumSwitchExample(Season s) {
switch(s) {
case WINTER:
System.out.println("It's pretty cold");
break;
case SPRING:
System.out.println("It's warming up");
break;
case SUMMER:
System.out.println("It's pretty hot");
break;
case FALL:
System.out.println("It's cooling down");
break;
}
}
You can also compare enum constants using ==
:
Season.FALL == Season.WINTER // false
Season.SPRING == Season.SPRING // true
Another way to compare enum constants is by using equals()
as below, which is considered bad practice as you can easily fall into pitfalls as follows:
Season.FALL.equals(Season.FALL); // true
Season.FALL.equals(Season.WINTER); // false
Season.FALL.equals("FALL"); // false and no compiler error
Furthermore, although the set of instances in the enum
cannot be changed at run-time, the instances themselves are not inherently immutable because like any other class, an enum
can contain mutable fields as is demonstrated below.
public enum MutableExample {
A,
B;
private int count = 0;
public void increment() {
count++;
}
public void print() {
System.out.println("The count of " + name() + " is " + count);
}
}
// Usage:
MutableExample.A.print(); // Outputs 0
MutableExample.A.increment();
MutableExample.A.print(); // Outputs 1 -- we've changed a field
MutableExample.B.print(); // Outputs 0 -- another instance remains unchanged
However, a good practice is to make enum
instances immutable, i.e. when they either don't have any additional fields or all such fields are marked as final
and are immutable themselves. This will ensure that for a lifetime of the application an enum
won't leak any memory and that it is safe to use its instances across all threads.
Enums implicitly implement Serializable
and Comparable
because the Enum
class does:
public abstract class Enum<E extends Enum<E>>
extends Object
implements Comparable<E>, Serializable