Java Enums
A Java Enum is a special Java type used to define collections of constants. More precisely, a Java enum type is a special kind of Java class. An enum can contain constants, methods etc. Java enums were added in Java 5.
This Java enum tutorial explains how to create and use a Java enum. If you prefer video, I have a video version of this tutorial here:
Enum Example
Here is a simple Java enum example:
Notice the enum keyword which is used in place of class or interface . The Java enum keyword signals to the Java compiler that this type definition is an enum.
You can refer to the constants in the enum above like this:
Notice how the level variable is of the type Level which is the Java enum type defined in the example above. The level variable can take one of the Level enum constants as value ( HIGH , MEDIUM or LOW ). In this case level is set to HIGH .
Enums in if Statements
Since Java enums are constants you will often have to compare a variable pointing to an enum constant against the possible constants in the enum type. Here is an example of using a Java enum in an if -statement:
Level level = . //assign some Level constant to it if( level == Level.HIGH) < >else if( level == Level.MEDIUM) < >else if( level == Level.LOW)
This code compares the level variable against each of the possible enum constants in the Level enum.
If one of the enum values occur more often than the others, checking for that value in the first if -statement will result in better performance, as less comparison on average are executed. This is not a big difference though, unless the comparisons are executed a lot.
Enums in switch Statements
If your Java enum types contain a lot constants and you need to check a variable against the values as shown in the previous section, using a Java switch statement might be a good idea.
You can use enums in switch statements like this:
Level level = . //assign some Level constant to it switch (level)
Replace the . with the code to execute if the level variable matches the given Level constant value. The code could be a simple Java operation, a method call etc.
Enum Iteration
You can obtain an array of all the possible values of a Java enum type by calling its static values() method. All enum types get a static values() method automatically by the Java compiler. Here is an example of iterating all values of an enum:
for (Level level : Level.values())
Running this Java code would print out all the enum values. Here is the output:
Notice how the names of the constants themselves are printed out. This is one area where Java enums are different than static final constants.
Enum toString()
An enum class automatically gets a toString() method in the class when compiled. The toString() method returns a string value of the name of the given enum instance. Here is an example:
String levelText = Level.HIGH.toString();
The value of the levelText variable after execution of the above statement will be the text HIGH .
Enum Printing
If you print an enum, like this:
System.out.println(Level.HIGH);
Then the toString() method will get called behind the scenes, so the value that will be printed out is the textual name of the enum instance. In other words, in the example above the text HIGH would have been printed.
Enum valueOf()
An enum class automatically gets a static valueOf() method in the class when compiled. The valueOf() method can be used to obtain an instance of the enum class for a given String value. Here is an example:
Level level = Level.valueOf("HIGH");
The level variable will point to the Level.HIGH after executing this line.
Enum Fields
You can add fields to a Java enum. Thus, each constant enum value gets these fields. The field values must be supplied to the constructor of the enum when defining the constants. Here is an example:
Notice how the Java enum in the example above has a constructor which takes an int . The enum constructor sets the int field. When the constant enum values are defined, an int value is passed to the enum constructor.
The enum constructor must be private . You cannot use public or protected constructors for a Java enum . If you do not specify an access modifier the enum constructor it will be implicitly private .
Enum Methods
You can add methods to a Java enum too. Here is an example:
public enum Level < HIGH (3), //calls constructor with value 3 MEDIUM(2), //calls constructor with value 2 LOW (1) //calls constructor with value 1 ; // semicolon needed when fields / methods follow private final int levelCode; Level(int levelCode) < this.levelCode = levelCode; > public int getLevelCode() >
You call a Java enum method via a reference to one of the constant values. Here is Java enum method call example:
Level level = Level.HIGH; System.out.println(level.getLevelCode());
This code would print out the value 3 which is the value of the levelCode field for the enum constant HIGH .
You are not restricted to simple getter and setter methods. You can also create methods that make calculations based on the field values of the enum constant. If your fields are not declared final you can even modify the values of the fields (although that may not be so good an idea, considering that the enums are supposed to be constants).
Enum Abstract Methods
It is possible for a Java enum class to have abstract methods too. If an enum class has an abstract method, then each instance of the enum class must implement it. Here is a Java enum abstract method example:
public enum Level < HIGH< @Override public String asLowerCase() < return HIGH.toString().toLowerCase(); >>, MEDIUM < @Override public String asLowerCase() < return MEDIUM.toString().toLowerCase(); >>, LOW < @Override public String asLowerCase() < return LOW.toString().toLowerCase(); >>; public abstract String asLowerCase(); >
Notice the abstract method declaration at the bottom of the enum class. Notice also how each enum instance (each constant) defines its own implementation of this abstract method. Using an abstract method is useful when you need a different implementation of a method for each instance of a Java enum.
Enum Implementing Interface
A Java Enum can implement a Java Interface in case you feel that makes sense in your situation. Here is an example of a Java Enum implementing an interface:
public enum EnumImplementingInterface implements MyInterface < FIRST("First Value"), SECOND("Second Value"); private String description = null; private EnumImplementingInterface(String desc)< this.description = desc; >@Override public String getDescription() < return this.description; >>
It is the method getDescription() that comes from the interface MyInterface .
Implementing an interface with an Enum could be used to implement a set of different Comparator constants which can be used to sort collections of objects. Sorting of objects in Java is explained in more detail in the Java Collection Sorting Tutorial.
EnumSet
Java contains a special Java Set implementation called EnumSet which can hold enums more efficiently than the standard Java Set implementations. Here is how you create an instance of an EnumSet :
EnumSet enumSet = EnumSet.of(Level.HIGH, Level.MEDIUM);
Once created, you can use the EnumSet just like any other Set.
EnumMap
Java also contains a special Java Map implementation which can use Java enum instances as keys. Here is a Java EnumMap example:
EnumMap enumMap = new EnumMap(Level.class); enumMap.put(Level.HIGH , "High level"); enumMap.put(Level.MEDIUM, "Medium level"); enumMap.put(Level.LOW , "Low level"); String levelValue = enumMap.get(Level.HIGH);
Enum Miscellaneous Details
Java enums extend the java.lang.Enum class implicitly, so your enum types cannot extend another class.
If a Java enum contains fields and methods, the definition of fields and methods must always come after the list of constants in the enum. Additionally, the list of enum constants must be terminated by a semicolon;
Enum Types
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.
In the Java programming language, you define an enum type by using the enum keyword. For example, you would specify a days-of-the-week enum type as:
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 timefor example, the choices on a menu, command line flags, and so on.
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(); >>
Mondays are bad. Midweek days are so-so. Fridays are better. Weekends are best. Weekends are best.
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. 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. This method is commonly used in combination with the for-each construct to iterate over the values of an enum type. For example, this code from the Planet class example below iterates over all the planets in the solar system.
for (Planet p : Planet.values())
Note: All enums implicitly extend java.lang.Enum . Because a class can only extend one parent (see Declaring Classes), the Java language does not support multiple inheritance of state (see Multiple Inheritance of State, Implementation, and Type), and therefore an enum cannot extend anything else.
In the following example, Planet is an enum type that represents the planets in the solar system. They are defined with constant mass and radius properties.
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.
Note: 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.
In addition to its properties and constructor, Planet has methods that allow you to retrieve the surface gravity and weight of an object on each planet. Here is a sample program that takes your weight on earth (in any unit) and calculates and prints your weight on all of the planets (in the same unit):
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 "); 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)); > >
If you run Planet.class from the command line with an argument of 175, you get this output:
$ java Planet 175 Your weight on MERCURY is 66.107583 Your weight on VENUS is 158.374842 Your weight on EARTH is 175.000000 Your weight on MARS is 66.279007 Your weight on JUPITER is 442.847567 Your weight on SATURN is 186.552719 Your weight on URANUS is 158.397260 Your weight on NEPTUNE is 199.207413
Previous page: Questions and Exercises: Nested Classes
Next page: Questions and Exercises: Enum Types