JavaObject-oriented programmingClasses and objects

Enum

Defining new enumeration types

An enum type (enumeration) is a special kind of Java class that enables for a variable to be a set of the predefined constant. The variable of an enum type is equal to one of the predefined constants.

According to the Java Code Convention, constants in an enum are written in uppercase letters.

Here is an example:

public enum Season {
    SPRING, SUMMER, AUTUMN, WINTER
}

The keyword enum is needed to declare a new enum type. Inside the body, all season constants are enumerated.

Here are a few other samples of enums:

  • Compass directions (NORTH, SOUTH, EAST, WEST);
  • Days of the week (SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY);

Processing enumerations

  • Let's initialize several variables of the Season type:
Season summer = Season.SUMMER; // SUMMER
Season autumn = Season.AUTUMN; // AUTUMN

  • Although an enum is a reference type, two variables can be correctly compared using both ways the method equals and the operator ==.
System.out.println(summer.equals(Season.SUMMER)); // true
System.out.println(summer == Season.SUMMER); // true

System.out.println(autumn.equals(Season.AUTUMN)); // true
System.out.println(autumn == Season.AUTUMN); // true

System.out.println(summer.equals(autumn)); // false
System.out.println(summer == autumn);      // false
  • It's possible to get all enum constants as an array:
Season[] seasons = Season.values(); // [SPRING, SUMMER, AUTUMN, WINTER]
  • Another useful feature is the creation of a variable from a string (case-sensitivity) :
Season season = Season.valueOf("AUTUMN"); // AUTUMN
  • If the given string doesn't match any constant the IllegalArgumentException happens.
Season winter = Season.valueOf("winter"); // IllegalArgumentException, valueOf is case-sensitive
  • Also, it's possible to get the string name of a constant using methods toString or name:
String winter = Season.WINTER.name(); // WINTER
String autumn = Season.AUTUMN.toString(); // AUTUMN

Enumerations in the switch statement

An enum type can be used in the switch statement.

For example, here is an enum with three possible user statuses:

public enum UserStatus {
    PENDING, ACTIVE, BLOCKED
}

Depending on the status, it is possible to perform different logic using the switch statement.

See the example below.

UserStatus status = ... // some status

switch (status) {
    case PENDING:
        System.out.println("You need to wait a little.");
        break;
    case ACTIVE:
        System.out.println("No problems, you may pass here.");
        break;
    case BLOCKED:
        System.out.println("Stop! You can't pass here.");
        break;
    default:
        System.out.println("Unsupported enum constant.");
} 

Depending on a value of the variable status this code outputs different message.

Defining fields and methods in enums

Enumerated types can include fields and methods.

Let's see an example. In a payment service, there are transactions exist. Each transaction has a status:

  • WAITING - a transaction is created and waits for processing;
  • PROCESSING - a transaction is still in processing;
  • COMPLETED - a transaction is completed;
  • ERROR - an error happens during processing.

Two statuses COMPLETED and ERROR are final for a transaction. It's done and won't be processed anymore.

public enum TransactionStatus {
    WAITING(false), 
    PROCESSING(false), 
    COMPLETED(true), 
    ERROR(true);
    
    private boolean done;

    TransactionStatus(boolean done) {
        this.done = done;
    }

    public boolean isDone() {
        return done;
    }
}

The enum above has the boolean field done, a single constructor that takes a boolean variable and the method isDone. Each enum constant is declared with a boolean value (done or not). The value is passed to the constructor when the constant is created.

Java requires that the constants be defined first, prior to any fields or methods. Also, when there are fields and methods, the list of enum constants must end with a semicolon.

Let's see the program printing full statuses of all transactions:

public class TransactionStatusDemo {

    public static void main(String[] args) {

        printFullStatus(TransactionStatus.WAITING);
        printFullStatus(TransactionStatus.PROCESSING);
        printFullStatus(TransactionStatus.COMPLETED);
        printFullStatus(TransactionStatus.ERROR);
    }

    private static void printFullStatus(TransactionStatus status) {
        System.out.println("Status: " + status + ", is finished: " + status.isDone());
    }
}

The output is:

Status: WAITING, is finished: false
Status: PROCESSING, is finished: false
Status: COMPLETED, is finished: true
Status: ERROR, is finished: true

Of course, an enum can contain more than one field. In this case, defining constants looks like:

AN_ENUM_CONSTANT(value1, value2, ... valueN)

And do not forget to write a constructor to initialize them.

You can read about enums in more detail here: https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html
How did you like the theory?
Report a typo