|
|||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||||
java.lang.Object | +--com.glaivestone.javax.lang.ConstantType
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.
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.
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.
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).
| 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 |
public final int ord
public final java.lang.String name
| Method Detail |
public static ConstantType getConstant(int ordinalValue,
java.lang.Class constantClass)
public static ConstantType getConstant(java.lang.String name,
java.lang.Class constantClass)
public int intValue()
public java.lang.String toConstantName()
public java.lang.String toDescriptionString()
public java.lang.String toIdentificationString()
public java.lang.String toQualifiedConstantName()
public java.lang.String toSimpleConstantName()
public java.lang.String toString()
toString in class java.lang.ObjectObject.toString()
|
GFL 1.1 API | ||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||||