What are constant-specific method bodies in a Java enum, and how do they let each constant behave differently?
answer
- Abstract method on enum forces every constant to implement
- Each bodied constant = anonymous subclass (Operation$1)
- Compile-time safety vs switch fall-through
- Operation/apply is the textbook example
- getDeclaringClass() returns the enum, getClass() the subclass
basics
~10 sEach enum constant can supply its own version of a method by writing a body in curly braces after the constant. So PLUS and MINUS can each compute differently while sharing one method name.
solid answer
~40 sAn enum can declare an abstract method; then every constant is forced to provide its own implementation in a body attached to the constant. This is called a constant-specific method body. Behind the scenes each such constant becomes an anonymous subclass of the enum, so the override is real polymorphism rather than a switch. The classic example is an Operation enum where PLUS, MINUS, TIMES, DIVIDE each implement apply(double a, double b) differently. The benefit over a switch-on-the-constant is that adding a new constant forces you to supply behavior (the abstract method won't compile otherwise), so you can't forget a case. You can also override a concrete (non-abstract) enum method per constant the same way to specialize just some constants while the rest use the default.
code
java · 13 linesenum Operation {
PLUS { public double apply(double a, double b) { return a + b; } },
MINUS { public double apply(double a, double b) { return a - b; } },
TIMES { public double apply(double a, double b) { return a * b; } };
public abstract double apply(double a, double b);
}
// usage
double r = Operation.TIMES.apply(2, 3); // 6.0
// each bodied constant is its own anonymous subclass:
assert Operation.PLUS.getClass() != Operation.class;
assert Operation.PLUS.getDeclaringClass() == Operation.class;go deeper
Knows you can give each enum constant its own method body and that the enum can declare an abstract method the constants implement.
Can write an Operation-style enum with an abstract method overridden per constant and explain why it beats a switch for safety.
Explains the anonymous-subclass compilation, virtual dispatch, getClass vs getDeclaringClass, and when a strategy/switch reads better.
Weighs constant-specific behavior against external strategy objects for maintainability, considers compile-time exhaustiveness as an API design guarantee, and the cost of many anonymous subclasses.
## What an enum is, first A Java **enum** (declared with the `enum` keyword) is a special kind of class whose instances are a fixed, named set written at the top of the body, e.g. `enum Color { RED, GREEN, BLUE }`. Each name like `RED` is a **constant**: a single, pre-created object of the enum type. You cannot make new ones with `new`. ## The problem constant-specific bodies solve Suppose you want each constant to *do* something different. A naive approach is one method with a `switch` over the constant: ```java enum Operation { PLUS, MINUS; double apply(double a, double b) { switch (this) { case PLUS: return a + b; case MINUS: return a - b; } throw new AssertionError("unknown op"); } } ``` This works but is fragile: if you add `TIMES` and forget a `case`, the code compiles and fails at runtime with the `AssertionError`. Nothing forced you to handle the new constant. ## Constant-specific method bodies Java lets each constant carry **its own body** — a block in `{ ... }` written right after the constant name. Combined with an **abstract method** on the enum, the compiler *forces* every constant to implement it: ```java enum Operation { PLUS { double apply(double a, double b) { return a + b; } }, MINUS { double apply(double a, double b) { return a - b; } }, TIMES { double apply(double a, double b) { return a * b; } }; abstract double apply(double a, double b); // every constant must implement } ``` Now `Operation.PLUS.apply(2, 3)` returns `5`, `Operation.TIMES.apply(2, 3)` returns `6`. If you add a fourth constant but forget its body, the program **does not compile** — a far safer failure than a runtime fall-through. ## How it works under the hood A constant with a body is compiled as an **anonymous subclass** of the enum. So `PLUS` is not an instance of `Operation` directly but of an unnamed class `Operation$1 extends Operation`, and `apply` is an ordinary override. Calls dispatch **virtually** (by the runtime type of the constant) — the same dynamic dispatch as any inherited method override. That is why it is real polymorphism, not a disguised switch. A visible consequence: `Operation.PLUS.getClass()` is not the same as `Operation.class`, and `Operation.PLUS.getDeclaringClass()` returns `Operation` (use `getDeclaringClass()` when you need the enum type itself). ## Overriding a concrete method per constant The method on the enum does not have to be `abstract`. You can give it a default and let only *some* constants override it: ```java enum Planet { EARTH, MARS { @Override String greeting() { return "Hello from Mars"; } }; String greeting() { return "Hello from " + name(); } // default for the rest } ``` Here `EARTH` uses the default, `MARS` uses its own. ## When to use it Reach for constant-specific bodies when behavior **belongs to** each constant and you want the compiler to guarantee completeness. Prefer it over a `switch` keyed on the enum precisely for that safety. If the behavior is external to the enum (e.g. depends on the caller's context), a separate strategy or a `switch` in the caller may read more cleanly.
- Why is an abstract method plus constant bodies safer than a switch over the enum?With an abstract method, the compiler refuses to compile any constant that lacks an implementation, so adding a constant can't silently miss a case. A switch can fall through to a default/throw at runtime instead.
- Why does Operation.PLUS.getClass() not equal Operation.class?A constant with a body becomes an anonymous subclass of the enum, so its runtime class is something like Operation$1. Use getDeclaringClass() to get the enum type itself.
Like a job description (the abstract method) that every employee (constant) must fill in with their own way of doing the task — HR won't onboard a new hire who left it blank.
saying these in an interview costs you the question
- Claiming constant-specific bodies are just syntactic sugar for a switch — they are real anonymous subclasses with virtual dispatch.
- Saying all constants share one method object; each bodied constant has its own override.
- Using getClass() to compare an enum constant's type to the enum type (it won't match for bodied constants).