Java Enum

java

// Enum
Enum is like a class but is used to declare constants. These constants are also objects.

// Enum

An enum can be simple or it can be a complex class.  When we need to implement
a complex enum, think of the keyword enum as the same as the keyword class. In
other words, an enum is a full blown class.  It can have constructors and 
methods.  Create the constructor function first.  The constructor function
should takes the necessary parameters.  All member variables must be declared
private final.  All the getter methods must be private.  The last thing that
we have to do is to put these constants at the top of this enum / class. 

public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
    THURSDAY, FRIDAY, SATURDAY 
}

Here is some code that shows you how to use the Day enum defined above:

public class EnumTest {
    Day day;

    public EnumTest(Day day) {
        this.day = day;
    }

    public void tellItLikeItIs() {
        switch (day) {
            case MONDAY:
                System.out.println("Mondays are bad.");
                break;

            case FRIDAY:
                System.out.println("Fridays are better.");
                break;

            case SATURDAY: case SUNDAY:
                System.out.println("Weekends are best.");
                break;

            default:
                System.out.println("Midweek days are so-so.");
                break;
        }
    }

    public static void main(String[] args) {
        EnumTest firstDay = new EnumTest(Day.MONDAY);
        firstDay.tellItLikeItIs();
        EnumTest thirdDay = new EnumTest(Day.WEDNESDAY);
        thirdDay.tellItLikeItIs();
        EnumTest fifthDay = new EnumTest(Day.FRIDAY);
        fifthDay.tellItLikeItIs();
        EnumTest sixthDay = new EnumTest(Day.SATURDAY);
        sixthDay.tellItLikeItIs();
        EnumTest seventhDay = new EnumTest(Day.SUNDAY);
        seventhDay.tellItLikeItIs();
    }
}

Enum can also be a full blown class.  The enum declaration 
defines a class (called an enum type). The enum class body can 
include methods and other fields.

Enum can have constructor functions. The constructor for an enum type must 
be package-private or private access. It automatically creates the constants 
that are defined at the beginning of the enum body. You cannot invoke an enum 
constructor yourself. Consider:

public enum Planet {
    MERCURY (3.303e+23, 2.4397e6),
    VENUS   (4.869e+24, 6.0518e6),
    EARTH   (5.976e+24, 6.37814e6),
    MARS    (6.421e+23, 3.3972e6),
    JUPITER (1.9e+27,   7.1492e7),
    SATURN  (5.688e+26, 6.0268e7),
    URANUS  (8.686e+25, 2.5559e7),
    NEPTUNE (1.024e+26, 2.4746e7);

    private final double mass;   // in kilograms
    private final double radius; // in meters

    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
    }

    private double mass() { return mass; }
    private double radius() { return radius; }

    // universal gravitational constant  (m3 kg-1 s-2)
    public static final double G = 6.67300E-11;

    double surfaceGravity() {
        return G * mass / (radius * radius);
    }
    double surfaceWeight(double otherMass) {
        return otherMass * surfaceGravity();
    }

    public static void main(String[] args) {
        if (args.length != 1) {
            System.err.println("Usage: java Planet <earth_weight>");
            System.exit(-1);
        }
        double earthWeight = Double.parseDouble(args[0]);
        double mass = earthWeight/EARTH.surfaceGravity();
        for (Planet p : Planet.values())
           System.out.printf("Your weight on %s is %f%n",
                             p, p.surfaceWeight(mass));
    }
}

In the above code, notice that this enum has a constructor function name 
Planet (same as the name of the enum / class). In side the enum, we can also 
have other methods just like a regular class. The constructor function takes 
2 parameters, mass and radius. These correspond to the parameters next to 
the enum constants at the top of the enum class. The compiler automatically 
invoke the constructor function with these parameters when it see these 
enum constants.

Each enum constant is declared with values for the mass and radius parameters. 
These values are 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.

The compiler automatically adds some special methods when it creates an enum. 
For example, they have a static values method that returns an array containing 
all of the values of the enum in the order they are declared.

for (Planet p : Planet.values()) {
    System.out.printf("Your weight on %s is %f%n",
                      p, p.surfaceWeight(mass));
}

Each enum constant is an object of the enum class. Each enum constant can have 
member variables. These member variables are private final.

What is enum?

Enum is like a class but is used to declare constants. These constants are also objects.

An enum type is a special data type that enables for a variable to be a set of predefined constants. The variable must be equal to one of the values that have been predefined for it. Common examples include compass directions (values of NORTH, SOUTH, EAST, and WEST) and the days of the week. Because they are constants, the names of an enum type's fields are in uppercase letters.

You should use enum types any time you need to represent a fixed set of constants. That includes natural enum types such as the planets in our solar system and data sets where you know all possible values at compile timeā€”for example, the choices on a menu, command line flags, and so on.

In the Java programming language, you define an enum type by using the enum keyword.

An enum can be simple:

public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
    THURSDAY, FRIDAY, SATURDAY 
}

Here is some code that shows you how to use the Day enum defined above:

public class EnumTest {
    Day day;

    public EnumTest(Day day) {
        this.day = day;
    }

    public void tellItLikeItIs() {
        switch (day) {
            case MONDAY:
                System.out.println("Mondays are bad.");
                break;

            case FRIDAY:
                System.out.println("Fridays are better.");
                break;

            case SATURDAY: case SUNDAY:
                System.out.println("Weekends are best.");
                break;

            default:
                System.out.println("Midweek days are so-so.");
                break;
        }
    }

    public static void main(String[] args) {
        EnumTest firstDay = new EnumTest(Day.MONDAY);
        firstDay.tellItLikeItIs();
        EnumTest thirdDay = new EnumTest(Day.WEDNESDAY);
        thirdDay.tellItLikeItIs();
        EnumTest fifthDay = new EnumTest(Day.FRIDAY);
        fifthDay.tellItLikeItIs();
        EnumTest sixthDay = new EnumTest(Day.SATURDAY);
        sixthDay.tellItLikeItIs();
        EnumTest seventhDay = new EnumTest(Day.SUNDAY);
        seventhDay.tellItLikeItIs();
    }
}

In the above code, do not be confused by the code inside the EnumTest constructor function, and the code inside the tellItLikeItIs function. The name of the class EnumTest can be anything such as TestOne.

Perhaps we can put the above code into its own file, just like a regular class file. To use the enum, we just have to import the file that contain the enum definition, and use it:

Day.SUNDAY

Can an enum represent a String?

Neither yes or no. All enums implicitly extend java.lang.Enum. Because a class can only extend one parent (the Java language does not support multiple inheritance) and therefore an enum cannot extend anything else.

I think Java internally manage different values for enum using integer constant, but SUNDAY is in a way the same as "SUNDAY".

Why do they say that Java enum is more powerful than other language?

Java programming language enum types are much more powerful than their counterparts in other languages. The enum declaration defines a class (called an enum type). The enum class body can include methods and other fields.

Enum can have constructor functions. The constructor for an enum type must be package-private or private access. It automatically creates the constants that are defined at the beginning of the enum body. You cannot invoke an enum constructor yourself. Consider:

public enum Planet {
    MERCURY (3.303e+23, 2.4397e6),
    VENUS   (4.869e+24, 6.0518e6),
    EARTH   (5.976e+24, 6.37814e6),
    MARS    (6.421e+23, 3.3972e6),
    JUPITER (1.9e+27,   7.1492e7),
    SATURN  (5.688e+26, 6.0268e7),
    URANUS  (8.686e+25, 2.5559e7),
    NEPTUNE (1.024e+26, 2.4746e7);

    private final double mass;   // in kilograms
    private final double radius; // in meters

    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
    }

    private double mass() { return mass; }
    private double radius() { return radius; }

    // universal gravitational constant  (m3 kg-1 s-2)
    public static final double G = 6.67300E-11;

    double surfaceGravity() {
        return G * mass / (radius * radius);
    }
    double surfaceWeight(double otherMass) {
        return otherMass * surfaceGravity();
    }

    public static void main(String[] args) {
        if (args.length != 1) {
            System.err.println("Usage: java Planet <earth_weight>");
            System.exit(-1);
        }
        double earthWeight = Double.parseDouble(args[0]);
        double mass = earthWeight/EARTH.surfaceGravity();
        for (Planet p : Planet.values())
           System.out.printf("Your weight on %s is %f%n",
                             p, p.surfaceWeight(mass));
    }
}

In the above code, notice that this enum has a constructor function name Planet (same as the name of the enum / class). In side the enum, we can also have other methods just like a regular class. The constructor function takes 2 parameters, mass and radius. These correspond to the parameters next to the enum constants at the top of the enum class. The compiler automatically invoke the constructor function with these parameters when it see these enum constants.

Each enum constant is declared with values for the mass and radius parameters. These values are 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.

The compiler automatically adds some special methods when it creates an enum. For example, they have a static values method that returns an array containing all of the values of the enum in the order they are declared.

for (Planet p : Planet.values()) {
    System.out.printf("Your weight on %s is %f%n",
                      p, p.surfaceWeight(mass));
}

Each enum constant is an object of the enum class. Each enum constant can have member variables. These member variables are private final.

Another example of complex enum:

enum Season {
  WINTER(1), SPRING(2), SUMMER(3), FALL(4);

  private int code;

  public int getCode() {
    return code;
  }

  Season(int code) {
    this.code = code;
  }

  public static Season valueOf(int code) {
    for (Season season : Season.values()) {
      if (season.getCode() == code) {
        return season;
      }
    }
    throw new RunTimeException("Invalid value");
  }
}

public void testGetCode() {
  Season winter = Season.WINTER;
  assertEquals(1, winter.getCode());
}

public void testCreateEnumFromCode() {
  Season winter = Season.valueOf(1);
  assertEquals(Season.WINTER, winter);
}

public int calculateMaxTemperature() {
  switch(this) {
    case WINTER:
      return 5;
    case SUMMER:
      return 20;
    case FALL:
      return 15;
    case SPRING:
      return 15;
  }
}

Season season = Season.WINTER;
season.name();

enum Season {
  WINTER, SPRING, SUMMER, FALL;
}

public void testCreateEnum() {
  Season season = Season.FALL;
  assertEquals(season.FALL, season);
}

// Using the .valueOf method of an enum
public void testCreateEnum() {
  Season season = Season.valueOf("WINTER");
  assertEquals(Season.WINTER, season);
}

// Using the .name() method of an enum 
public void testCreateEnum() {
  Season season = Season.WINTER;
  assertEquals("WINTER", season.name());
}

// Using the .values() method of the enum class
public void loopAroundEnum() {
  ArrayList<String> enumValues = new ArrayList<String>();
  for (Season season : Season.values()) {
    enumValues.add(season.name());
  }
  assertEquals(Arrays.asList("WINTER","SPRING","SUMMER","FALL"), enumValues);
}

Misc:

enum E { A, B }
Class c = A.getClass();

A is is an instance of the enum E; thus getClass() returns the Class corresponding to the enumeration type E.

import java.util.EnumSet;
for (people x:  EnumSet.range(people.kelsey, tuna.candy)) { ... }
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License