skip to content

How do you add fields, a constructor, and methods to an enum, and why is the constructor implicitly private?

level: middleimportance: must knowfreq 70%

answer

  1. Args after constant name -> matching constructor + final fields
  2. Semicolon ends the constant list before members
  3. Constructor implicitly private: no new, closed instance set
  4. Constants built in declaration order at class init, before later statics
  5. Fields final -> immutable shared singletons, thread-safe

basics

~20 s

List each constant with constructor arguments in parentheses, then declare instance fields, a constructor, and methods after a semicolon. The constructor is implicitly private because you may not create new enum instances — the JVM creates them all at load time.

solid answer

~50 s

An enum can carry state and behavior like any class. You attach data to each constant by passing arguments after the constant name, then declare matching final fields, a constructor, and accessor methods. For example `enum Planet { EARTH(5.97e24, 6.37e6); private final double mass, radius; Planet(double m, double r){...} double gravity(){...} }`. The constructor is **implicitly private** (you cannot mark it public or protected) because enum instances are a fixed set created once by the JVM at class-load time — letting callers invoke the constructor would allow new, unlisted instances, breaking the closed-set guarantee. The constants are constructed in declaration order before any other static initialization completes, so a constant cannot reference a static field of the enum that is initialized later. Fields are conventionally final to keep constants immutable, which is important because each constant is a shared singleton.

code

java · 16 lines
java
public enum Coin {
    PENNY(1), NICKEL(5), DIME(10), QUARTER(25);

    private final int cents;

    Coin(int cents) {        // implicitly private; cannot be public
        this.cents = cents;
    }

    public int cents() { return cents; }

    public int countValue(int n) { return n * cents; }
}

// usage
int total = Coin.QUARTER.countValue(4); // 100

go deeper

for a junior

Can add a field and constructor to an enum and pass values per constant; knows the constructor is not called with new.

for a middle

Explains why the constructor is implicitly private, the required semicolon, and that fields should be final because constants are shared singletons.

for a senior

Discusses construction ordering, the static-field-from-constructor pitfall, overloaded enum constructors, and thread-safety from immutability.

for a principal

Weighs enum-with-behavior as a domain-modeling tool (state machines, strategy tables), addresses initialization-order hazards in large enums, and immutability guarantees in concurrent systems.

## Enums are full classes Unlike a bare list of names, an enum can hold **state** (fields) and **behavior** (methods). This is what makes Java enums far more powerful than other languages' enum-as-int. ## Attaching data to constants To give each constant data, put the constructor arguments in parentheses after the constant name, and declare a matching constructor and fields: ```java public enum Planet { MERCURY(3.30e23, 2.44e6), EARTH(5.97e24, 6.37e6); // <- semicolon required before members private final double massKg; private final double radiusM; Planet(double massKg, double radiusM) { // implicitly private this.massKg = massKg; this.radiusM = radiusM; } double surfaceGravity() { final double G = 6.674e-11; return G * massKg / (radiusM * radiusM); } } ``` Key syntax rules: - The **constant list comes first** in the body. - A **semicolon** terminates the constant list when fields/methods follow. - Each constant's parentheses supply arguments to a matching constructor (overloaded constructors are allowed; `MONDAY` with no args uses a no-arg constructor). ## Why the constructor is implicitly private A **constructor** is the special method that initializes a new instance. For a normal class you call `new Foo()`. For an enum, the **complete set of instances is fixed** — exactly the constants you listed. To enforce that, the language makes the enum constructor **implicitly private**: you cannot declare it `public` or `protected`, and you cannot write `new Planet(...)` anywhere. Only the enum's own constant declarations can invoke it, and the JVM does so **once per constant** when the enum class is initialized. This guarantees the closed-set, singleton-per-constant property. ## Construction timing and ordering The constants are constructed **in the order they are declared**, as part of the enum class's static initialization, **before** any subsequent static initializer or static field assignment runs. A practical consequence: a constant's constructor **cannot read a static field** of the same enum that is initialized later (it will see the default/null value). This is the classic enum-constructor pitfall — e.g. trying to register each constant into a static `Map` from within the constructor before that map field exists. ## Why fields should be final Each constant is a **shared singleton** — there is exactly one `Planet.EARTH` for the whole program. If a field were mutable, any code could change the shared state seen by everyone. So enum fields are conventionally **`private final`**, making constants effectively immutable and therefore safe to share across threads without synchronization. ## Methods on enums You can add ordinary instance methods (like `surfaceGravity()` above), static helper methods, and override inherited methods such as `toString()`. All constants share the same method bodies unless you use *constant-specific* bodies (a separate topic). ## Summary Attach data via constructor arguments after each constant, back them with final fields, and rely on the implicitly-private constructor to keep the instance set closed. Beware referencing later-initialized statics from the constructor, and keep fields immutable since constants are shared singletons.

  • Can an enum have more than one constructor?
    Yes. Enum constructors can be overloaded; each constant's argument list selects a matching constructor (or the no-arg one when no parentheses are given). All constructors are still implicitly private.
  • What goes wrong if you reference a static field from the enum constructor?
    Constants are constructed first, before later static initializers run, so the static field is still at its default (e.g. null). A common bug is populating a static lookup map from the constructor — it NPEs or registers into a not-yet-created map. Initialize such maps lazily or in a static block after the constants.

saying these in an interview costs you the question

  • Trying to make the enum constructor public or protected
  • Writing new EnumType(...) to make a constant
  • Reading a later-initialized static field from inside the enum constructor
  • Using mutable enum fields and assuming per-use isolation (constants are shared)

context