Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Create enumerated constants in Java

The weaknesses of Java's static finals are defined here and a template is provided for creating typesafe constants

  • Print
  • Feedback

Page 5 of 6

  public final class Color {
    private String id;
    public final int ord;
  private Color prev;
  private Color next;

private static int upperBound = 0; private static Color first = null; private static Color last = null; private Color(String anID) { this.id = anID; this.ord = upperBound++; if (first == null) first = this; if (last != null) { this.prev = last; last.next = this; } last = this; } public String toString() {return this.id; } public static int size() { return upperBound; } public static Color first() { return first; } public static Color last() { return last; } public Color prev() { return this.prev; } public Color next() { return this.next; }
public static final Color RED = new Color("Red"); public static final Color GREEN = new Color("Green"); public static final Color BLUE = new Color("Blue"); }


Whenever a new constant object is created, it is linked to the last constant object, and the last constant object is linked to it. The static methods first() and last() return the end points of the list, while the methods prev() and next() move from object to object within the list. The beauty of all this is that once the class is set up, you only have to modify the last few lines to create or remove constants from the class; their order is determined by the order in which you create them.

Enumerations

The last modification is to extend the class so that you can use a standard Enumeration interface, like this:

  import java.util.*;
  ...
  Enumeration e = Color.elements();
  while (e.hasMoreElements()) {
    Color c = (Color) e.nextElement();
    ...
  }


The Enumeration interface is defined in java.util, so that package needs to be imported. The interface says that the object has two methods. One method, hasMoreElements(), returns a boolean. The other, nextElement(), returns an object of type Object -- which forces you to cast it to an object of type Color using (Color) in order to assign the value to a Color variable.

The really cool and largely unsung merit of interfaces is that you can use an interface as a data type! The elements method in Color will return an object, and that object will belong to a special class. But the user won't even care what that class is! The only relevant feature of the class will be that it implements the Enumeration interface. The method invoking the class can then write:

  Enumeration e = Color.elements();


regardless of what the actual class is that elements() returns.

Here are the modifications necessary to return a class that implements the Enumeration interface:

  import java.util.*;

public final class Color { private String id; public final int ord; private Color prev; private Color next;
private static int upperBound = 0; private static Color first = null; private static Color last = null; private Color(String anID) { this.id = anID; this.ord = upperBound++; if (first == null) first = this; if (last != null) { this.prev = last; last.next = this; } last = this; } public static Enumeration elements() { return new Enumeration() { private Color curr = first; public boolean hasMoreElements() { return curr != null; } public Object nextElement() { Color c = curr; curr = curr.next(); return c; } }; } public String toString() {return this.id; } public static int size() { return upperBound; } public static Color first() { return first; } public static Color last() { return last; } public Color prev() { return this.prev; } public Color next() { return this.next; }
public static final Color RED = new Color("Red"); public static final Color GREEN = new Color("Green"); public static final Color BLUE = new Color("Blue"); }


This code uses an "anonymous (inner) class." Both anonymous classes and inner classes are new in Java 1.1. An inner class is a class that is defined inside of another class -- so it cannot be used outside of that class. An anonymous class is one without a name -- a "one-shot" class that is used to instantiate a single object. An anonymous class can be used either to extend an existing class or to implement an interface. In this case, it implements the Enumeration interface. The "new" operator creates a new object using the definition in the curly braces that follow it.

  • Print
  • Feedback

Resources