Java Enums and Interfaces

Last update: 2024-06-05 02:14:10 +0800 +0800
tags: Enums | Java
Available translations: 日本語 / 中文(简体) / 中文(繁體)

An enum declaration defines a final class with a fixed set of instances. Each constant is an instance of that class, which conceptually extends Enum<E> with the enum type as E; no user enum may extend another class. The compiler supplies values() and valueOf(String), while Enum supplies the name, ordinal, comparison, and serialization rules.

Interfaces and Constant-Specific Behavior #

An enum may implement interfaces, and the implementation can be shared by all constants or supplied in a constant-specific class body.

java
enum Operation {
    ADD { int apply(int a, int b) { return a + b; } },
    SUBTRACT { int apply(int a, int b) { return a - b; } };

    abstract int apply(int a, int b);
}

Each constant-specific body is an anonymous subclass generated by the compiler. Virtual dispatch therefore selects its override. The enclosing enum remains a closed set, so this is an effective Strategy implementation when strategies are known at compile time. Prefer injected interface implementations when extensions must be installed independently.

Constant-specific bodies may implement an abstract enum method. An enum-level implementation is appropriate when behavior is shared. Keep mutable state out of enum constants unless its lifecycle is deliberately process-wide: enum instances are initialized once by their defining class loader.

Identity, Order, and Collections #

Enum serialization preserves singleton identity: deserialization resolves the constant by name rather than allocating a new instance. clone is prohibited, and reflective construction of enum instances is prohibited. Use == for enum identity and avoid persisting ordinal(), because inserting or reordering constants changes it. Persist name() only when its source-level stability is an explicit contract; an external code field is safer for long-lived data.

Enum.compareTo orders constants by declaration order. EnumSet represents a set compactly using the constants’ ordinals, and EnumMap indexes values by enum key. Both require one enum type and are preferable to general-purpose collections when that constraint is natural.

java
EnumSet<Operation> enabled = EnumSet.of(Operation.ADD);
EnumMap<Operation, String> labels = new EnumMap<>(Operation.class);
labels.put(Operation.ADD, "addition");

References #

Comments

Read or comment on GitHub (sign-in required to comment)