Free Java Tutorials >> Table of contents >> Enums

1. Enums

Enumerations

Unlike a class, an enum type has a predefined constant set of states. A variable of an enum type must equal one of the predefined states. For example, an enum representing compass directions could have the states NORTH, SOUTH, EAST, and WEST. Similarly, you could have an enum with states representing months such as JANUARY, FEBRUARY, MARCH, etc. Here's an enum for the compass directions:

enum Direction {
	NORTH, SOUTH, EAST, WEST
}
//Now you can create the following code in a main method:
//Direction direction = Direction.NORTH;
//if(direction == Direction.EAST) {
//   System.out.println("To the sun!");
//}

Fields and Constructors, and methods

Unlike constant values in some other languages, Java enum types can have fields, constructors, and methods. In this way, they are very much like classes. Here, we can create a field int angle in the enum Direction. Once a constructor is set, each state (EAST, SOUTH, etc) must call the constructor:

enum Direction {
    EAST(0), SOUTH(90), WEST(180), NORTH(270);
    
    int angle;
    //The constructor is run when the enum is loaded
    //Often this is when the enum is first used in a program
    Direction(int angle) {
        this.angle = angle;
        System.out.println("Created angle with direction: "+angle);
    }
    public String toString() {
		//By default the Enum.toString() prints the state name, like "SOUTH"
        return super.toString() + " has angle "+angle;
    }
}

public class MyProgram {
    public static void main(String[] args) {
        System.out.println("Get ready to use some enums!");
        Direction south = Direction.SOUTH;
        System.out.println(south);
    }
}

Looping through all states

Much like a map, you can loop through each of an enums states with the values() method. This method is static. In the example of enum Direction, you could use the following code:

//In some method somewhere:
for(Direction d : Direction.values()) {
	//use d
}

Static fields

Like classes, enums can have static fields. However, due to the way enums are constructed, you cannot access the static fields in the constructor. Here's an example of a Direction enum that uses a static hashmap to map from angles:

import java.util.*;

enum Direction {
    EAST(0), SOUTH(90), WEST(180), NORTH(270);
    
    static Map<Integer,Direction> directionByAngle
        = new LinkedHashMap<Integer,Direction>();
    
    int angle;
    //The constructor is run when the enum is loaded
    //Often this is when the enum is first used in a program
    Direction(int angle) {
        this.angle = angle;
        System.out.println("Created angle with direction: "+angle);
    }
    public static Direction getDirection(int angle) {
        if(directionByAngle.size()==0) {
            for(Direction d : Direction.values()) {
                directionByAngle.put(d.angle,d);
            }
        }
        return directionByAngle.get(angle);
    }
    public String toString() {
        return super.toString() + " has angle "+angle;
    }
    public Direction clockwise90() {
        int nextAngle = (angle+90)%360;
        return getDirection(nextAngle);
    }
    public Direction counterclockwise90() {
        int nextAngle = (angle-90+360)%360;
        return getDirection(nextAngle);
    }
}

public class MyProgram {
    public static void main(String[] args) {
        System.out.println("Get ready to use some enums!");
        Direction dir = Direction.SOUTH;
        for(int i = 0 ; i < 10; i++) {
            System.out.println(dir);
            if(i<5) {
                System.out.println("Turning counterclockwise");
                dir = dir.counterclockwise90();
            }else {
                System.out.println("Turning clockwise");
                dir = dir.clockwise90();
            }
        }
    }
}

Previous: Oop Modifiers

Next: References