skip to content

What are constant-specific method bodies in a Java enum, and how do they let each constant behave differently?

level: middleimportance: should knowfreq 55%

answer

  1. Abstract method on enum forces every constant to implement
  2. Each bodied constant = anonymous subclass (Operation$1)
  3. Compile-time safety vs switch fall-through
  4. Operation/apply is the textbook example
  5. getDeclaringClass() returns the enum, getClass() the subclass

basics

~10 s

Each 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 s

An 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 lines
java
enum 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

for a junior

Knows you can give each enum constant its own method body and that the enum can declare an abstract method the constants implement.

for a middle

Can write an Operation-style enum with an abstract method overridden per constant and explain why it beats a switch for safety.

for a senior

Explains the anonymous-subclass compilation, virtual dispatch, getClass vs getDeclaringClass, and when a strategy/switch reads better.

for a principal

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).

context