Enum
       An Amazing Enum Implementation for Java

Unlike its ancestors (C and C++)  Java does not support the notion of an enum, which is a data type all values of which are explicitly enumerated in the type definition.

That said, an object-oriented implementation of the concept of enum in Java can be much more powerful than C-style enum.

The Enum framework (in reality, the whole framework is a single class) proves that by providing extensive functionality that includes:

 
Either an integer or string value or both for each constant
A human-readable description that can be easily internationalized.  An enum type is automatically associated with .properties files containing labels of enums in specific languages.
All constants of an Enum can be loaded from a .properties file.
Every Enum type is represented by a separate class extending the Enum abstract class (see API)
 

Basic Enum

The easiest way to define an Enum type is to declare a class that extends Enum and a separate instance of that class as a public static field of the class itself.
public class Color extends Enum
{
    public static Color RED = new Color();
    public static Color GREEN = new Color();
    public static Color BLUE = new Color();
}
This class is accompanied by a Color.properties file that is located in the same package as the Color class:
RED=Red
GREEN=Green
BLUE=Blue
Italian names of colors are in Color_it_IT.properties file:
RED=Rosso
GREEN=Verde
BLUE=Azzurro
The following table contains values returned by various methods of Color:
 
  Color.RED Color.GREEN Color.BLUE
intValue() 0 1 2
stringValue() "RED" "GREEN" "BLUE"
toString() "Red" "Green" "Blue"
toString(Locale.ITALY) "Rosso" "Verde" "Azzurro"
Enum provides the following automation: Class Enum has some useful static methods:
Color allColors[] = (Color[])Enum.enum(Color.class);
This method will return all Colors in the order they are declared: Color.RED, Color.GREEN, Color.BLUE
Color green = (Color)Enum.enum(Color.class, "GREEN");
This method will the Color constant by its string value
Color blue = (Color)Enum.enum(Color.class, 2);
This method will the Color constant by its integer value
Enums can be used as types of properties of JavaBeans:
public class Crayon {

   private Color color;

   public void setColor(Color color){
      this.color = color;
   }

   public Color getColor(){
      return color;
   }

   ...
}

Crayon crayon = new Crayon();
crayon.setColor(Color.GREEN);

System.err.println("Questo pastello è " +
           crayon.getColor().toString(Locale.ITALY));
 
 

Explicit String Values and Labels

String values and/or labels of constants can be specified explicitly:
public class Gender extends Enum
{
    public static Gender FEMALE = new Gender("F", "Female");
    public static Gender MALE = new Gender("M", "Male");

    protected Gender(String string, String label){
        super(string, label);
    }
}

Spanish words for genders are in Gender_es.properties file:
F=Feminino
M=Masculino
The default labels are used when the .properties file for the corresponding locale is missing.

The following table contains values returned by various methods of Gender:

 
  Gender.FEMALE Gender.MALE
intValue() 0 1
stringValue() "F" "M"
toString() "Female" "Male"
toString(new Locale("es", "MX")) "Feminino" "Masculino"
toString(Locale.ITALY) "Female" "Male"

Explicit Integer Values

Integer values of constants can alse be specified explicitly:
public class Order extends Enum {

    public static Order LESS_THAN = new Order(-1);
    public static Order EQUAL_TO = new Order(0);
    public static Order GREATER_THAN = new Order(1);

    protected Order(int integer){
        super(integer);
    }
}

The following table contains values returned by various methods of Order:
 
  Order.LESS_THAN Color.EQUAL_TO Color.GREATER_THAN
intValue() -1 0 1
stringValue() "LESS_THAN" "EQUAL_TO" "GREATER_THAN"
toString() "LESS_THAN" "EQUAL_TO" "GREATER_THAN"

 

Integer Enums

If you need to use an Enum in switch statements, you may want to declare integer constants instead of objects of the enum class.  The static method Enum.initIntegerEnum method of Enum should be invoked from a static code fragment of the Enum class:
public class Employment extends Enum {

    public static final int EMPLOYED = 1;
    public static final int SELF_EMPLOYED = 2;
    public static final int UNEMPLOYED = 3;

    static {
        // Register all 'public static ints' of this class as Enums
        initIntegerEnum(Employment.class);
    }
}

String values and labels of the constants can be acquired using the following calls:
Enum employed = Enum.enum(Employment.class, Employment.EMPLOYED);
String string = employed.stringValue();
String label = employed.toString();
In this case both the string value and the label will be "EMPLOYED". Just like any Enum, such integer Enum can be internationalized - the public static int field names function as keys in the .properties file.

The following table contains values returned by various methods of Order:

 
  Enum.enum(
   Employment.class,
   Employment.EMPLOYED)
Enum.enum(
   Employment.class,
   Employment.UNEMPLOYED)
intValue() 1 3
stringValue() "EMPLOYED" "UNEMPLOYED"
toString() "EMPLOYED" "UNEMPLOYED"

 

Loading Enums from a File

If it is preferred to keep constant definitions in a file and not define individual constants for each value, that can also be done:
public class Flower extends Enum
{
    static {
        // Load all Enums of this class from Flower.properties
        loadEnum(Flower.class);
    }

    // Define any of the Flower constants individually
    public static Flower ROSE = enum("rose");

    /**
     * Convenience method that finds a Flower object by its name.
     */
    public static Flower enum(String name){
        return (Flower)enum(Flower.class, name);
    }
}

The Flower.properties file:
rose=Rosa
daisy=Chrysanthemum leucanthemum
violet=Viola
forget-me-not=Myosotis
An integer Enum can be loaded the same way, except instead of the loadEnum method the loadIntegerEnum method should be called.  Property names in the .properties file should then be numeric.

Note: if you are using one of the load... methods, do not allocate any additional constants, find the loaded once like we did in the Flower class.
 

Download

The class is freely available under the PLOTNIX license.

JavaDoc
Download ZIP (includes JAR, docs and source)
 

Enjoy!


Copyright © 2001, PLOTNIX, Inc

Java, JavaSoft, are trademarks or registered trademarks of Sun Microsystems, Inc.