Skip to content

Enums

Enums are special types of objects in the Java language. Their main feature is ability to define fixed number of instances for a given type. In order to create an enum, we need to create a file with java extension and then define an enum with the same name as the file. We define enums similarly to classes but use enum keyword instead of class, e.g.:

public enum ExampleEnum {
 // enum content 
}

Defining enums

Each enum can define any number of predefined values. We always define them at the very beginning of the enum body. Possible values are usually written using capital letters and values are separated by a comma, e.g.:

public enum JsonSerializationStrategy {
  SNAKE_CASE,
  CAMEL_CASE,
  KEBAB_CASE
}

Getting enum instances

In order to retrieve enum instance, we use dot notation, e.g.:

JsonSerializationStrategy strategy = JsonSerializationStrategy.SNAKE_CASE;

It is impossible to create new enum instance with usage of the new keyword:

JsonSerializationStrategy jsonSerializationStrategy = new JsonSerializationStrategy(); // impossible for enums

Comparing enums

Enums' instances are created on application startup. Each value in created once. Because of that it makes sense to compare enum values with either equals method or ==:

JsonSerializationStrategy strategyA = JsonSerializationStrategy.CAMEL_CASE;
JsonSerializationStrategy strategyB = JsonSerializationStrategy.CAMEL_CASE;
System.out.println(strategyA == strategyB); // true
System.out.println(strategyA.equals(strategyB)); // true

Class similarities

Enums are quite similar to classes. Besides defining list of possible values enums can:

Enums do have some limits. It is impossible to:

  • extend an enum
  • extend other class in enum

Constructors and enum fields

In case enum uses any other mechanism besides listing possible values, it is mandatory to use ; after all definitions.

Each enum can define multiple constructors and all of them should be private (or preferably not define any access modifier). In case a constructor uses input parameters, those parameters have to be specified for each enum value, e.g.:

public enum JsonSerializationStrategy {
  SNAKE_CASE("snake case"),
  CAMEL_CASE("camel case"),
  KEBAB_CASE("kebab case");

  private final String readableName;

  JsonSerializationStrategy(final String readableName) {
    this.readableName = readableName;
  }
}

Methods and interfaces

Each enum, just like any class, can implement interfaces and define methods, e.g.:

public enum JsonSerializationStrategy implements IdProvider {
  SNAKE_CASE("snake case"),
  CAMEL_CASE("camel case", "1"),
  KEBAB_CASE("kebab case", "2");

  private final String readableName;
  private final String id;

  JsonSerializationStrategy(final String readableName) {
    this.readableName = readableName;
    this.id = "0";
  }

  JsonSerializationStrategy(final String readableName, final String id) {
    this.readableName = readableName;
    this.id = id;
  }

  public String getReadableName() {
    return readableName;
  }

  @Override
  public String getId() {
    return id;
  }
}

To call a method, we should use dot notation, just like for any class:

JsonSerializationStrategy strategy = JsonSerializationStrategy.CAMEL_CASE;
System.out.println(strategy.getId() + " " + strategy.getReadableName());

Inheritance

Enums cannot extend a class. The following code will not compile:

public class SomeBaseClass {
}
public enum EnumExample extends SomeBaseClass {
}

Other classes also cannot extend an enum. The following code will also not compile:

public enum EnumExample {
}
public class SomeBaseClass extends EnumExample {
}

Built-in methods

Each enum has access to following static methods:

  • values - returns array of all possible enum values
  • valueOf - returns enum instance based on input name

Each enum instance has name() method which returns name of the instance as String.

Following example shows usage of those methods:

public enum Difficulty {
  EASY,
  MEDIUM,
  HARD
}
Stream.of(Difficulty.values()).forEach(System.out::println); // EASY MEDIUM HARD
System.out.println(Difficulty.valueOf("EASY") == Difficulty.EASY); // true
System.out.println(Difficulty.MEDIUM.name()); // MEDIUM