Time to open the Champagne -- Java 1.5 is out, and the language has finally come of age! With the new Java 1.5 specification, Java now contains features that make it feel like a proper "grown-up" language. The rest of this article will introduce you to these new features. To try out the features for yourself, simply download Java 1.5 from Sun’s website and give it a whirl. Note that you’ll need to compile the code using the –source 1.5 option; otherwise, you’ll get compilation errors when using the new features.
Personally, the omission of "proper" enumerations in earlier versions of Java really annoyed me. I still can't believe how Java survived so long without it. In versions of Java prior to 1.5, the typical approach to represent the suit of a playing card would be something like the following:
public
interface CardSuit { public static final int HEARTS = 0; public static final int SPADES = 1; public static final int CLUBS = 2; public static final int DIAMONDS = 3; }
The problem is that this representation is not type-safe: it is too easy to mix up an int that represents the suit of a card with another int such as a loop counter. It could be made type-safe by writing a class with a private constructor:
public
class CardSuit { public static final Suit HEARTS = new Suit(); public static final Suit SPADES = new Suit(); public static final Suit CLUBS = new Suit(); public static final Suit DIAMONDS = new Suit();
private Suit() {} }
In this case, the only instances of the class Suit that will ever exist are those that are created inside the class itself. It guarantees type-safety, but is long-winded and not easy to read. In Java 1.5, you can create an enumerated type in a single line as follows:
public enum CardSuit
{ hearts, spades, clubs, diamonds };
Think of the enum keyword as an alternative to class, as similar restrictions apply. As with classes, public enumerations must be in a file named after the enumeration, but the same restriction does not apply to package level enumerations. Inner enumerations (if that is the correct terminology) are also permitted, and can be public:
package card
;
public class Card { public enum CardValue { ace, two, three, four, five, six, seven, eight, nine, ten, jack, queen, king };
private CardSuit suit; private CardValue value;
public Card(CardValue newValue, CardSuit newSuit) { suit = newSuit; value = newValue; }
public CardSuit getSuit() { return suit; }
public CardValue getValue() { return value; }
public String toString() { return value+" of "+suit; } }
You can refer to the inner enumeration and its allowed values using the dot notation: Card.CardValue.ace, for example.