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:
- define constructors
- define fields
- define methods
- implement interfaces
- use access modifiers
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 valuesvalueOf
- 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