enum in Java
Motivation
- Understand how to write an enum type in Java.
Basic definitions and instance methods
public class Main {
public static void main(String[] args) {
try {
System.out.printf("LogLevel.valueOf(): %s\n", LogLevel.valueOf("LOW"));
System.out.printf("LogLevel.valueOf().getClass(): %s\n", LogLevel.valueOf("LOW").getClass());
System.out.printf("LogLevel.valueOf(): %s\n", LogLevel.valueOf("NONE"));
} catch (Exception e){
System.out.println(e);
}
System.out.println();
// Testing enum's constructor
for (LogLevel logLevel: LogLevel.values()) {
System.out.println("--------------------START-----------------------");
System.out.printf("# Log level: %s\n", logLevel);
System.out.printf("instance of LogLevel?: %b\n",logLevel instanceof LogLevel);
System.out.println();
// Testing getter method
System.out.println("## Testing sefl-implemented instance methods");
System.out.printf("getLogLevel(): %s\n", logLevel.getLogLevel());
System.out.println();
// Testing enum instance methods
System.out.println("## Testing common instance methods");
System.out.printf("toString(): %s\n", logLevel.toString());
System.out.printf("name(): %s\n", logLevel.name());
System.out.printf("ordinal(): %s\n", logLevel.ordinal());
System.out.println("---------------------END------------------------");
System.out.println();
}
}
}
public enum LogLevel {
// These enum constants use the constructor defined below.
LOW("low"),
MEDIUM("medium"),
HIGH("high");
private final String logLevel;
LogLevel(String logLevel) {
this.logLevel = logLevel;
}
public String getLogLevel() {
return this.logLevel;
}
}
Output
$ java Main.java
LogLevel.valueOf(): LOW
LogLevel.valueOf().getClass(): class LogLevel
java.lang.IllegalArgumentException: No enum constant LogLevel.NONE
--------------------START-----------------------
# Log level: LOW
instance of LogLevel?: true
## Testing sefl-implemented instance methods
getLogLevel(): LOW
## Testing common instance methods
toString(): LOW
name(): LOW
ordinal(): 0
---------------------END------------------------
--------------------START-----------------------
# Log level: MEDIUM
instance of LogLevel?: true
## Testing sefl-implemented instance methods
getLogLevel(): MEDIUM
## Testing common instance methods
toString(): MEDIUM
name(): MEDIUM
ordinal(): 1
---------------------END------------------------
--------------------START-----------------------
# Log level: HIGH
instance of LogLevel?: true
## Testing sefl-implemented instance methods
getLogLevel(): HIGH
## Testing common instance methods
toString(): HIGH
name(): HIGH
ordinal(): 2
---------------------END------------------------
Conditional statement using enum (switch)
with Java 17
public class Main {
public static void main(String[] args) {
LogLevel currentLevel = LogLevel.LOW;
LogLevel.detectCurrentLogLevel(currentLevel);
}
}
public enum LogLevel {
// These enum constants use the constructor defined below.
LOW("low"),
MEDIUM("medium"),
HIGH("high");
private final String logLevel;
LogLevel(String logLevel) {
this.logLevel = logLevel;
}
public String getLogLevel() {
return this.logLevel;
}
public static void detectCurrentLogLevel(LogLevel currentLevel) {
switch (currentLevel) {
case LOW, MEDIUM -> {
System.out.printf("Current level: %s\n", currentLevel);
}
case HIGH -> {
System.out.printf("Current level: %s\n", currentLevel);
}
default -> {
// never reached
System.out.printf("Unknow log level");
}
}
}
}
with Java 11
public class Main {
public static void main(String[] args) {
LogLevel currentLevel = LogLevel.LOW;
LogLevel.detectCurrentLogLevel(currentLevel);
}
}
public enum LogLevel {
// These enum constants use the constructor defined below.
LOW("low"),
MEDIUM("medium"),
HIGH("high");
private final String logLevel;
LogLevel(String logLevel) {
this.logLevel = logLevel;
}
public String getLogLevel() {
return this.logLevel;
}
public static void detectCurrentLogLevel(LogLevel currentLevel) {
switch (currentLevel) {
case LOW:
System.out.printf("Current level: %s\n", currentLevel);
break;
case MEDIUM:
System.out.printf("Current level: %s\n", currentLevel);
break;
case HIGH:
System.out.printf("Current level: %s\n", currentLevel);
break;
default:
// never reached
System.out.printf("Unknow log level");
}
}
}
Output
$ java Main.java
Current level: LOW
Note
We cannot use switch-case
expression in Java 11 but can use switch-case
statements (break
keyword is necessary to stop fall through).
Java SE 12 introduced switch expressions, which (like all expressions) evaluate to a single value, and can be used in statements. It also introduced “arrow case” labels that eliminate the need for break statements to prevent fall through.
EnumSet
import java.util.EnumSet;
public class Main {
// Create an union set from enum constants
private static final EnumSet<LogLevel> acceptableLevel = EnumSet.of(LogLevel.LOW, LogLevel.MEDIUM);
public static boolean isAcceptableLevel(LogLevel level) {
return acceptableLevel.contains(level);
}
public static void main(String[] args) {
var currentLevel = LogLevel.HIGH;
if (isAcceptableLevel(currentLevel)) {
System.out.printf("Safe to ignore\n Level is %s\n", currentLevel.toString());
} else {
System.out.printf("Something wrong is happening!!\nLevel is %s\n", currentLevel.toString());
}
}
}
public enum LogLevel {
// These enum constants use the constructor defined below.
LOW("low"),
MEDIUM("medium"),
HIGH("high");
private final String logLevel;
LogLevel(String logLevel) {
this.logLevel = logLevel;
}
public String getLogLevel() {
return this.logLevel;
}
}
Output
$ java Main.java
Something wrong is happening!!
Level is HIGH
EnumMap
import java.util.EnumMap;
public class Main {
public static void main(String[] args) {
// Create a map accpeting keys defined in the enum type
EnumMap<LogLevel,String> logLevelMap = new EnumMap<>(LogLevel.class);
System.out.println("# initial map");
System.out.println(logLevelMap);
System.out.println("# value filled map");
logLevelMap.put(LogLevel.LOW, "low level");
logLevelMap.put(LogLevel.MEDIUM, "medium level");
logLevelMap.put(LogLevel.HIGH, "high level");
System.out.println(logLevelMap);
}
}
public enum LogLevel {
// These enum constants use the constructor defined below.
LOW("low"),
MEDIUM("medium"),
HIGH("high");
private final String logLevel;
LogLevel(String logLevel) {
this.logLevel = logLevel;
}
public String getLogLevel() {
return this.logLevel;
}
}
Output
$ java Main.java
# initial map
{}
# value filled map
{LOW=low level, MEDIUM=medium level, HIGH=high level}