Enums with Fields & Methods
Enums with Fields & Methods
A plain enum whose constants are just names is useful, but it only scratches the surface. In Java, every enum is a full class — and that means each constant can carry its own data and expose behaviour. This lesson shows you how to give enum constants constructors, fields, and methods, and explains why doing so often beats a parallel array or a utility class full of static maps.
Why attach data to constants?
Imagine you model the planets of the solar system. You could store each planet's mass and radius in a separate HashMap, but then every piece of code that needs a planet's mass has to look it up by key and risk a null. A far better design is to let the constant itself carry the data — then the data and the constant are inseparable and always in sync.
Enum constructors and fields
Add a constructor to an enum exactly like you would to a regular class — but note two rules: the constructor is always private (Java enforces this), and each constant must supply the required arguments in parentheses right after its name.
You can now write expressive code with zero external data structures:
private Planet(...) is legal but redundant. You cannot make an enum constructor public or protected — the language forbids it because only the compiler creates enum instances.
Enums as a replacement for int constants
A very common real-world use is HTTP status codes or database error codes that need both a numeric value and a human-readable message:
Usage becomes readable and type-safe:
toString() purposefully. The default toString() returns the constant name (e.g. "NOT_FOUND"). Overriding it to return a meaningful representation — like "404 Not Found" — makes logs and error messages much clearer without any extra ceremony at the call site.
Lookup methods — finding a constant by its field value
A common need is the reverse lookup: given a status code integer coming in from a network response, you want the matching HttpStatus constant. The idiomatic approach is a static factory method on the enum itself:
For performance-critical hot paths with many constants, pre-build a Map in a static initialiser:
values() must appear after the constant list in the source file, otherwise the JVM will throw an ExceptionInInitializerError at startup. The enum constants are always initialised first.
Abstract methods — per-constant behaviour
Sometimes each constant needs a different implementation of the same operation. You can declare an abstract method on the enum and provide a body for each constant using an anonymous-class-style override:
This pattern is powerful because the compiler forces you to implement apply for every constant. Add a new operation? The compiler immediately tells you if you forgot to implement the method.
Implementing interfaces
An enum can implement one or more interfaces, which is particularly useful when you want to treat enum constants and regular objects polymorphically:
java.lang.Enum), but they can implement as many interfaces as needed. Use this when you want a group of constants to fit into an existing polymorphic design without introducing a separate class hierarchy.
Summary
Java enums are classes. Each constant is a singleton instance of that class, constructed once by the JVM. Giving constants fields and a private constructor bundles data with the constant so it can never get out of sync. Methods on the enum — including abstract ones with per-constant bodies — let each constant encapsulate its own behaviour. This produces code that is type-safe, readable, and easy to extend: adding a new constant forces you to supply all required data and behaviour, and the compiler checks your work.