THE Java™ Programming Language, Fourth Edition

(Jeff_L) #1

The constructor to invoke is determined according to the usual rules for matching argument types with
constructor parameter typessee "Finding the Right Method" on page 224.


There are three restrictions on the definition of an enum constructor:


All enum constructors are private. While you can use the private access modifier in the constructor
declaration, by convention it is omitted. Private constructors ensure that an enum type cannot be
instantiated directly.


The constructor cannot explicitly invoke a superclass constructor. The chaining to the super
constructor is handled automatically by the compiler.



  • An enum constructor cannot use a non-constant static field of the enum.


This last restriction requires a little explanation. Because each enum constant is a static field of the enum type,
the constructors are executed during static initialization of the enum class. The enum constant declarations
must be the first declarations in the type, so the constructors for these values will always be the first code
executed during static initialization. Any other static fields will be initialized afterward. So if a constructor
were to refer to a static (non-constant) field of the enum, it would see the default uninitialized value. This
would nearly always be an error, and so it is simply disallowed.


The work-around is quite straight-forward: Declare a static initialization block that does what the constructor
would like to have done. This block can refer to any enum constant or can iterate through all of them because
all will have been constructed before the block can execute.


Exercise 6.4: Expand your traffic light color enum from Exercise 6.1 on page 152 so that each enum constant
has a suitable Color object that can be retrieved with getColor.


6.3.2. Constant Specific Behavior


Many enums define simple, passive types whose sole purpose is to provide the named enum constantsan enum
like Suit is a good example. Occasionally, enum constants will have state associated with them that will be
set by a constructor and accessed with a method on the enum. For example, consider an enum that defined the
nine planets of our solar system, and that allowed the mass of each planet to be set and queried. In some
circumstances, the enum may represent an entity with inherent behavior that varies between the different
enum constantsthis is known as constant-specific behavior.


Suppose you were writing a computer chess program[2] and you wanted to represent the different kinds of
chess pieces, you might use a simple enum like this:


[2] This example is based on an example given by Tim Peierls.

enum ChessPiece {
PAWN, ROOK, BISHOP, KNIGHT, KING, QUEEN;
}


The rules for manipulating the different chess pieces could be defined in a class ChessRules, which might
then have a method that returns the set of reachable positions for a given kind of piece, given its current
position:


Set reachable(ChessPiece type, Position current) {
if (type == ChessPiece.PAWN)
return pawnReachable(current);
else if (type == ChessPiece.ROOK)
return rookReachable(current);

Free download pdf