An enum class (Java 5) is a class with a fixed set of instances, the enum
constants, named in its declaration. No other instances can ever exist, so
constants can be compared with == (JLS 8.9).
Declaration
EnumDeclaration:
{ClassModifier} enum TypeIdentifier [ClassImplements] EnumBody
EnumBody:
{ [EnumConstantList] [,] [EnumBodyDeclarations] }
EnumConstant:
{EnumConstantModifier} Identifier [( [ArgumentList] )] [ClassBody]
EnumBodyDeclarations:
; {ClassBodyDeclaration}
enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY }
public enum Planet {
MERCURY(3.303e+23, 2.4397e6),
EARTH (5.976e+24, 6.37814e6),
JUPITER(1.9e+27, 7.1492e7); // the semicolon ends the constant list
private static final double G = 6.67300E-11;
private final double mass, radius;
Planet(double mass, double radius) { // implicitly private
this.mass = mass;
this.radius = radius;
}
double surfaceGravity() { return G * mass / (radius * radius); }
}
- The constants come first, separated by commas; a trailing comma is allowed. If anything follows them, they end with a semicolon.
- Each constant is a
public static finalfield of the enum type, and may carry annotations and arguments for a constructor. - An enum’s direct superclass is
Enum<E>. It cannot have anextendsclause, but may implement interfaces. - An enum cannot be declared
abstract,final,sealedornon-sealed. It is implicitlyfinal, unless a constant has a class body, when it is implicitlysealed, with those bodies as its only subclasses. - Nested and local enums are implicitly
static. - An enum may be empty:
enum None {}, orenum Util { ; static void f() {} }.
Constructors and initialisation
- Constructors are implicitly
private;publicorprotectedis an error. They cannot callsuper(…). newon an enum type is an error, and so is cloning or creating an instance by reflection; serialisation reads constants back by name, so they stay unique.- The constants are created in order, when the enum class is initialised, before its other static fields. So a constructor or instance initialiser may not refer to a static field of the enum unless it is a constant variable: the field would not be set yet.
Constant-specific class bodies
A constant may have a class body, which declares an anonymous subclass of the enum for that constant alone. This gives each constant its own method implementations:
enum Operation {
PLUS("+") { int apply(int a, int b) { return a + b; } },
MINUS("-") { int apply(int a, int b) { return a - b; } },
TIMES("*") { int apply(int a, int b) { return a * b; } };
final String symbol;
Operation(String symbol) { this.symbol = symbol; }
abstract int apply(int a, int b); // allowed: every constant implements it
}
An enum may declare an abstract method only if it has at least one constant and every constant has a body that implements it. A constant body cannot declare constructors.
Implicit members
| Member | From | What it does |
|---|---|---|
public static E[] values() | Implicit | A new array of the constants, in declaration order |
public static E valueOf(String name) | Implicit | The constant with exactly that name; IllegalArgumentException if none |
name() | Enum | The constant’s name as declared; final |
ordinal() | Enum | Its position, from 0; final |
compareTo(E) | Enum | Compares by ordinal; final |
toString() | Enum | The name, unless overridden |
equals, hashCode | Enum | Identity; final |
getDeclaringClass() | Enum | The enum class, even for a constant with a body |
describeConstable() | Enum | A nominal descriptor of the constant (Java 12) |
An enum may not declare its own values(), valueOf(String),
or a finalize method. java.util has
EnumSet and EnumMap, compact collections keyed by
ordinal.
Enums in switch
A switch on an enum value uses the bare constant names as labels. Since Java 21 the
qualified name, such as Day.MONDAY, is allowed too, which matters when
the selector is of a sealed interface type that enums implement. A switch expression
over an enum is exhaustive when it lists every constant, with no default.
The compiler then adds a hidden default that throws an error, in case a constant is
added to the enum later and the switch is not recompiled.
static boolean weekend(Day d) {
return switch (d) {
case SATURDAY, SUNDAY -> true;
case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> false;
};
}
See Switch for the full rules.