# Java Notes

# Enums

Problem: How to represent a set of named constant values. First we'll look at the "old" Java solution, then see how Java 5 enums substantially improve the situation.

## Older, but common, solution

Just define a number of public static final int constants. For example:

    //... Constants to represent possible shapes.
    public static final int RECTANGLE = 0;
    public static final int CIRCLE    = 1;
    public static final int LINE      = 2;
    ...
    int drawing = RECTANGLE;   // But any int could be assigned.

These values can then be assigned to an integer variable, and can be used in switch statements. This style is useful, but is not a great solution.

- Allows illegal values. Any variable containing one of these values could also be assigned any integer value, although there are only three legal choices. Eg,

      drawing = 99;   // Illogical value, but allowed by compiler.

- Updates not reflected in other code. If there are additions, deletions, or reorderings, code from other classes will not automatically be readjusted to reflect these changes. All code that uses these definitions would have to be recompiled.
- No easy I/O. To convert values to and from a string form requires maintaining an additional array and lookup code.
- Fragile for loops. There is no obvious first and last value so iterating over all values is subject to errors which are not diagnosed at compile time if the values are rearranged, deleted, or added to. There is no way to use the enhanced for loop.
- No behavior. This style is pre-OOP -- there are values, but no behavior defined for them.

## Defining an enum type

An enum type is a kind of class definition. The possible enum values are listed in the curly braces, separated by commas. By convention the value names are in upper case.

    public enum Shape { RECTANGLE, CIRCLE, LINE }

## Declaring enum variables and using enum values

The enum class name can be use like any other class type in declarations. Usually enum values must be prefixed with the enum type name.

    Shape drawing = Shape.RECTANGLE;   // Only a Shape value can be assigned.

## Printing enum values

The enum class has a `toString()` method defined that returns the unqualified string version of the value. This means that it's easy to print these values without any special conversion effort.

    System.out.println(drawing);    // Prints RECTANGLE

## Looping over all enum values with foreach loop

The static `values()` method of an enum type returns an array of the enum values. The foreach loop is a good way to go over all of them.

    //... Loop over all values.
    for (Shape shp : Shape.values()) {
        System.out.println(shp);       // Prints RECTANGLE, CIRCLE, ...
    }

## Switch statement

The `switch` statement was enhanced to allow a convenient use of enums. Note that the case values don't have to be qualified with the enum class name, which can be determined from the `switch` control value.

    switch (drawing) {
        case RECTANGLE: g.drawRect(x, y, width, height);
                        break;
        case CIRCLE   : g.drawOval(x, y, width, height);
                        break;
        case LINE     : g.drawLine(x, y, x + width, y + height);
                        break;
    }

## Getting an integer equivalent of an enum value

Each enum value in an enum class has an associated default value, starting with zero for the first value and incrementing by one for each additional value. This may be accessed with the `ordinal()` method.

    System.out.println(drawing.ordinal());     // Prints 0 for RECTANGLE.

## Input

The `valueOf()` method can be used to convert a string value to an enum value. Here is an example of reading in a Shape value from a Scanner object in.

    drawing = Shape.valueOf(in.next());

## Defining additional fields, methods, and constants for your enum type

Methods can be defined for an enum class, including defining a different method body for each of the constants. See the Sun article for examples of this. If you are using switch statements with cases for each of the enum constants, consider putting the code into the enum class.

## Related data structure classes: EnumSet and EnumMap

The java.util.EnumSet class provides an efficient implementation of sets of enums as bit maps, or powersets as they were called in Pascal. EnumSet can also generate an Iterable for use with subsets in the for-each statement.

java.util.EnumMap provides an efficient implementation of a map for enums based on an array.

## Further reading

- Enums is a good Sun overview of the Java enum features. It's very readable with good examples.
- Example: PaintDemo is a small paint program which represents the shape with an enum. It shows how to use an enum to represent simple constants, and also how to associate a method with each constant.
- Class Enum<E extends Enum<E>> is the API documentation for the superclass of all enums. You'll find useful methods in this class such as `compareTo(...)`, `ordinal()`, `toString()`, and `valueOf(...)`. The addition of generics negated the former Java claim to simplicity, and it's this Enum definition which is often used as an example of the incomprehensible. It's hard to find anyone who understands this obscure declaration. Fortunately, the use of enums doesn't require that that you know what this declaration means.
- Java language - Enum Switch discusses proposals for making enums in switch statements more robust.