Enums with fields & methods in Java
Constructors (implicitly private), fields, methods, constant-specific bodies.
Enums are full classes
An enum can have fields, a constructor and methods. Arguments after a constant, like PENNY(1), are passed to the constructor, which runs once per constant. So each constant carries its own data.
enum Coin {
PENNY(1), NICKEL(5), DIME(10);
final int cents;
Coin(int cents) { this.cents = cents; }
}
Coin.DIME.cents; // 10Constructor rules
The enum constructor is implicitly private — writing public is a compile error, because nobody outside may create new constants. And when the enum has other members, the constant list comes first and must end with a semicolon.
enum Coin {
PENNY(1), DIME(10); // <- semicolon!
final int cents;
private Coin(int c) { cents = c; } // ok
// public Coin(...) -> compile error
}Who gets built?
Only GO is used. What prints?
enum Signal {
STOP, GO;
Signal() { System.out.print(name() + " "); }
}
void main() {
Signal a = Signal.GO;
Signal b = Signal.GO;
System.out.println(a == b);
}STOP GO trueGO trueGO GO trueSTOP GO false
Show the answer
The first use initializes the whole enum, which constructs all constants, once, in order. Later uses reuse the same objects, so a == b is true.
The missing semicolon
With fields or methods after the constants, forgetting the ; that ends the constant list is a compile error. The compiler reads final double gravity as if it were another constant.
enum Planet {
MERCURY(3.7), EARTH(9.8) // error
final double gravity;
Planet(double g) { gravity = g; }
}Constant-specific bodies
A constant can have its own class body overriding a method. Declare an abstract method in the enum, and every constant must implement it. MUL.apply(3, ADD.apply(1, 1)) is 3 * 2 = 6.
enum Op {
ADD {
int apply(int a, int b) { return a + b; }
},
MUL {
int apply(int a, int b) { return a * b; }
};
abstract int apply(int a, int b);
}Why not a switch?
You could write one apply method with a switch over this. Why might constant-specific bodies be safer?
Think about it, then reveal the answer
Add a new constant and the compiler forces you to give it a body (the method is abstract). With a switch, a forgotten case can slip by. The behaviour also lives right next to the constant it belongs to.
Enums with brains
java.util.concurrent.TimeUnit is an enum whose constants carry conversion logic: TimeUnit.MINUTES.toSeconds(2) returns 120. Real apps use the same idea for currencies with symbols, HTTP statuses with codes, or pricing tiers with limits.
Key takeaways
- PENNY(1) passes 1 to the constructor
- Enum constructors are implicitly private; public is a compile error
- List the constants first and end the list with ; before other members
- Constant bodies: ADD { int apply(...) { ... } }
A constant with its own body is compiled as an anonymous subclass of the enum, so Op.ADD.getClass() is not Op.class — use getDeclaringClass() to get the enum type back.
Practice questions
What does this print?
enum Coin {
PENNY(1), NICKEL(5), DIME(10);
final int cents;
Coin(int c) { cents = c; }
}
void main() {
int sum = 0;
for (Coin c : Coin.values()) sum += c.cents;
System.out.println(sum);
}- 16
- 3
- 0
- Compile error
Check your answer
16. Each constant stored its own cents value via the constructor: 1 + 5 + 10 = 16.
What does this print?
enum Light {
RED, GREEN;
Light() { System.out.print(name() + " "); }
}
void main() {
Light a = Light.GREEN;
Light b = Light.GREEN;
System.out.println(a == b);
}- RED GREEN true
- GREEN GREEN true
- GREEN true
- RED GREEN false
Check your answer
RED GREEN true. The first use of Light initializes the enum, which constructs ALL constants once. Later uses reuse the same objects, so a == b.