com.glaivestone.javax.lang
Class ConstantType

java.lang.Object
  |
  +--com.glaivestone.javax.lang.ConstantType
Direct Known Subclasses:
EnumerationType, FileType

public class ConstantType
extends java.lang.Object

ConstantType is the abstract superclass for classes which implement efficient, readable, type-safe constant values. A constant is uniquely identified within its constant type by an integer ordinal value. Constants also have unuique String names which identify them within their constant type.

Constants are immutable - the state of the constant is fixed at creation time and cannot be modified. Constants can be efficiently compared using the == identity operator. Unique identity within the constant type is an invariant of the implementation and can be relied upon by clients.

The instance variables of a constant are exposed directly to clients to provid a succint notation for referencing the ordinal value and identifying name of the constant:

     aConstant.ord	// the ordinal value of the constant
     aConstant.name	// the name of the constant
 

In addition to being type-safe, immutable values, constants can can add value by providing behavior or by supporting predicates related to the constant value which simplify client code using the constants.

Usage Notes

There is a regrettable awkwardness in using constants as the discriminating value in a switch statement. Although you can use the ordinal value of the constant as the switch expression (e.g., switch (aConstant.ord) {...}), you cannot use the ordinal for the case constant expressions in the switch, even though the ordinal values of the constants are immutable values that are fixed at creation time. If you cannot find a way to write your client logic using polymorphic protocol, then you can introduce explicit int ordinal constants in the constant class which "double-up" the actual constant definitions for use in switch statements. E.g., for each constant MyConstant FOO that you declare, "shadow" it with a int FOO_ORD declaration that can be used on switch case expressions.

Note: This technique should only be used if necessary. The implementor must absolutely ensure the correctness of the shadowing ordinal declarations (see the validateOrdinalConstant method). This technique is only applicable for a closed set of constants, since the shadow ordinal constants must be fixed at development time.

Subclass Responsibilities

Subclasses are responsible for providing an implementation which allocates unique ordinal values to newly constructed constants. Subclasses are also responsible for specifying the semantics of ordinal values with respect to whether clients can rely on the ordinal values being fixed. In general, clients can rely on the name being fixed but not the ordinal value.

Subclasses are also responsible for providing an implementation which ensures that the identifying name attribute of a constant is unique with the set of constants of that type.

Subclass implementors can choose whether to their constant type represents an open or closed set of constants. Both flavors are useful. A closed set is completely defined in the implementing class and typically is enforced by means of a restricted access modifier on the constant constructor(s). An open set of constants is supported by implementing a public service which allows arbitrary clients to create constants which conform to the invariant conditions that the ordinal and name values of a constant are unique within that constant type.

The constant implementation framework takes no position on whether constants are serializable or persistable. Subclass implementors may provide such a capability if they deem it appropriate. The recommended technique for externalizing a constant is to use the constant's name value as the external representation and to provide appropriate resolution to the actual constant when the external representation is restored. For a Serializable constant class, the implementation must provide a suitable readResolve. For other external representations, equivalent capability must be provided in the subclass implementation to preserve the class invariant that the ordinal and identifying name values of a constant are unique and that clients can rely on constants being unique instance that can be compared with the == identity operator.

It is left to the discretion of the creator of a constant type to follow some convention so that the identifying names of constant variables are assigned appropriately. E.g., typically you would like the constant's .name attribute to be consistent with the identifer of the variable which references that constant (interface constant or static final variable referencing the constant).

Subclass implementations may allow synonym names, such that (presumably) minor variations of a constant's name are allowed when resolving a constant reference by name to the actual constant using the getConstant(String) service. Constant types which support synonym names are responsible for registering the mapping from all supported synonyms to the intended constant. Facilities are provided in the ConstantType framework to support managing a synonym registry and performing lookup during name resolution.

Origins

The concepts and implementation of this class were derived in part from articles by Eric Armstrong and Thomas E. Davis in the July and September 1999 issues of Java World. The technique of type-safe enumerations in Java is also described in Joshua Bloch's Effective Java (Addison-Wesley/Sun Microsystems, 2001).

Author:
Deb Lewis

Field Summary
 java.lang.String name
          The string value which uniquely identifies this constant within its type.
 int ord
          The ordinal value which uniquely identifies this constant within its type.
 
Method Summary
static ConstantType getConstant(int ordinalValue, java.lang.Class constantClass)
          Answer the constant of the specified type with the specified ordinal value.
static ConstantType getConstant(java.lang.String name, java.lang.Class constantClass)
          Answer the constant of the specified type with the specified name.
 int intValue()
          Answer the ordinal value of the constant.
 java.lang.String toConstantName()
          Answer a string representation of the constant formed from the constant type name and its identifying name.
 java.lang.String toDescriptionString()
          Answer a description of the constant.
 java.lang.String toIdentificationString()
          Answer a string representation which fully identifies the constant.
 java.lang.String toQualifiedConstantName()
          Answer a string representation of the constant formed from the fully qualified constant type name and its identifying name.
 java.lang.String toSimpleConstantName()
          Answer a string representation of the constant formed from the simple (unqualified) constant type name and its identifying name.
 java.lang.String toString()
          Returns a string representation of the constant.
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

ord

public final int ord
The ordinal value which uniquely identifies this constant within its type.


name

public final java.lang.String name
The string value which uniquely identifies this constant within its type.

Method Detail

getConstant

public static ConstantType getConstant(int ordinalValue,
                                       java.lang.Class constantClass)
Answer the constant of the specified type with the specified ordinal value. Returns null if not defined.


getConstant

public static ConstantType getConstant(java.lang.String name,
                                       java.lang.Class constantClass)
Answer the constant of the specified type with the specified name. Returns null if not defined.


intValue

public int intValue()
Answer the ordinal value of the constant.


toConstantName

public java.lang.String toConstantName()
Answer a string representation of the constant formed from the constant type name and its identifying name.


toDescriptionString

public java.lang.String toDescriptionString()
Answer a description of the constant.


toIdentificationString

public java.lang.String toIdentificationString()
Answer a string representation which fully identifies the constant.


toQualifiedConstantName

public java.lang.String toQualifiedConstantName()
Answer a string representation of the constant formed from the fully qualified constant type name and its identifying name.


toSimpleConstantName

public java.lang.String toSimpleConstantName()
Answer a string representation of the constant formed from the simple (unqualified) constant type name and its identifying name.


toString

public java.lang.String toString()
Returns a string representation of the constant.

Overrides:
toString in class java.lang.Object
See Also:
Object.toString()

GFL 1.1 API