December 12, 2004
After 8 years or so Java finally adds enums, I guess there is still hope for D
adding a true boolean type in the future.
from JDJ magazine:
Exploring Enums: The Wait Is Finally Over
November 30, 2004
To enumerate means to itemize or to list. In the world of programming,
enumerations, enums for short, are used to represent a finite set of
values (constants) that a variable can attain. In other words, it defines the
domain of a type. For instance, different states of a fan switch - off,
low, medium, and high - make up an enumeration.

By Ajith Kallambella

To enumerate means to itemize or to list. In the world of programming,
enumerations, enums for short, are used to represent a finite set of
values (constants) that a variable can attain. In other words, it defines the
domain of a type. For instance, different states of a fan switch - off, low,
medium, and high - make up an enumeration.

Since the first release of Java, programmers have been complaining
about the lack of core language support for enumerated types. After all, Java
improvised on the shortcomings of C++ and touted type safety, so it was
only natural for the developer community to expect support for a true
enum-type. During what seemed like an eternally long wait, many ad-hoc
enum representations evolved and most of them shared a common premise -
modeling enumerations based on a primitive type, usually an int; see Listing 1
for an example.

Although practical, such implementations have long been frowned upon by
Java purists as a hack that can best be described as brittle. What
exactly is wrong with such an implementation? In essence, the main disadvantage
of faking enumerated types using primitives is the lack of strong typing
and hence the inability to catch errors at compile time. Other shortcomings
are less readable code, deviations from object-oriented concepts such as
encapsulation, the absence of a namespace requiring an explicit prefix
for all references, and the dangers of exposing the internal implementation
to client code.

Let's look at some of these drawbacks in more detail.

Loose type checking is the result of a compiler treating the faked
enumeration just like any other primitive variable. Since the compiler
doesn't know anything about the cohesiveness of the enumeration of
values, it doesn't catch, for instance, a definitive assignment of an
of range value. In other words, lack of an explicit type totally gives
the benefits of compile-time error detection.

Such ad hoc approaches violate some of the basic object-oriented
principles. In the previous example, the states of the switch lack
encapsulation. Attributes representing the constants and operations are
grouped together but are scattered within the enclosing scope. Since
client code is well aware of implementation details, even a small
such as renumbering them might result in broken client code. Also note
lack of explicit scoping. Since enum attributes are listed along with
class attributes, the enclosing scope is often that of the declaring
or interface. This makes their grouping vague, unreadable, and
error prone.

In his book Effective Java, Joshua Bloch presents a pattern for
enums that offers both compile-time safety and better encapsulation.
java.awt.Color uses a similar strategy to hide the int-enum
under the sheet. However, after reading through pages full of Java
you begin to wonder if the juice is worth the squeeze. It only
the need for core language support for enum types. For a language that
touts type safety, the idea of faking enums with such elaborate
pyrotechnics seems rather odd.

Enter the New Enum
The wait is finally over and true enums are here. Enums are a type of
own in J2SE 5.0. Among many other developer-friendly features
in JSR 176, Tiger (the code name for the new release) packs the
punch of type-safe enums. Listing 2 shows how we rewrite using
true enums. (Listings 2-9 can be downloaded from

Note the new enum keyword introduced to support the new type and also
enumerated constants are listed - they are neither strings nor ints but
belong to their own declared type, i.e., SwitchState. Because it's a
type, all the benefits of strong typing automatically kick in. For
instance, the following code attempting to set an invalid state

new Fan().setState(6);

is automatically detected at compile time and reported an error, eliminating the need for several lines of validation code:

setState(Fan.SwitchState) in Fan cannot be applied to (int)

Let's look at other useful features provided by the enum type.

Support for Namespace
In the previous example, all the listed constants, e.g., states of the
switch, implicitly belong to the enclosing type, appropriately named
SwitchState, requiring an explicit namespace qualification to all
references to states. For example:


Namespace adornment also helps avoid collisions. If we were to declare another enum type for class Fan using a similar set of constants, say:

public enum DurabilityRating { Low, Medium, High }

it will result in no name collision. SwitchState.Low can be
from DurabilityRating.Low because of their enclosing scope.

Since enum SwitchState is declared as public, and with the type system
providing a namespace for each enum constant, it can be accessed
the scope of class Fan just like any normal attribute reference, e.g.,

Auto Conversion to String Values
The new enum type easily facilitates descriptive printing using an
implementation of the toString() method. The default implementation
a string representation of the constant as declared, and, if you don't
it, it can be changed by overriding toString(). It's that simple.

Works with Programming Constructs
Since enums are their own types, some of the standard Java constructs,
notably the switch and for statements, have been enhanced to work with
types. Listing 3 provides an example of the switch construct.

Switch statements are useful for simulating the addition of a method to
enum type from outside the type. This can be very useful if for some
the enum definition cannot be modified, but needs to be extended.

There is something rather interesting about this switch statement -
how the enum constants in case statements appear bare, e.g.,
with their namespace. J2SE 5.0 makes life easier by attempting to
identifiers in the immediate context. This is somewhat similar to the
static imports feature. In this example, however, you are required to
the namespace. Try including it and you'll get an error message: an enum switch case label must be the unqualified name of
enumeration constant
case SwitchState.Off : return SwitchState.Low ;

Listing 4 provides an example that uses a for-loop construct to iterate through enums.

The values() method returns an array that contains enum constants for
enum in the order in which they are declared. By the way, the for-loop
shown here is called "enhanced for-loop", another neat feature in the
release. They are also called as "for-in loop" since you read them as
"for-state-in-Switchstate.values". This new construct simplifies
over a collection of values - both arrays and Java collections - by
away the need to inspect the size, use a temporary index variable, and
each element to the appropriate type.

Looking Under the Hood
In the spirit of empiricism, let's look under the hood and see how
are implemented. Compiling (for the complete source code see
resources section) generates two .classes: Fan.class and
Fan$SwitchState.class. The latter contains our enum definition.

D:\MyJava\JDJ\src>javap  Fan$SwitchState

Compiled from ""
public final class Fan$SwitchState extends java.lang.Enum{
public static final Fan$SwitchState Off;
public static final Fan$SwitchState Low;
public static final Fan$SwitchState Medium;
public static final Fan$SwitchState High;
public static final Fan$SwitchState[] values();
public static Fan$SwitchState valueOf(java.lang.String);
static {};

As you can see, the process of compilation results in the automatic
generation of a new class that extends java.lang.Enum. In other words,
enum keyword acts as a shorthand representation for the autogenerated
class. This is what the authors of JSR 201 meant by "linguistic support
type-safe enumeration pattern." It's worth mentioning that every new
language extension introduced in Java 5.0 is implemented by modifying
source-to-byte code compiler so the JVM implementation remains

If you notice the naming convention adopted for generated enum types,
you'll recognize that they closely resemble the inner class syntax,
<enclosingType>$<thisType> format. All enum classes are final
subclasses of
java.lang.Enum, serializable, and comparable. They come with predefined
toString, hashCode, and equals methods. All methods except toString are

Note that all enlisted enum constants are represented as final
variables of the class. This is done to ensure no instances exist other
than those in the generated class. In other words, enums are Singletons
and, for the same reason, they can't be instantiated using new or
The clone method in java.lang.Enum throws a CloneNotSupportedException.

Since enums are compiled into their own class files, their definition
be changed, e.g., enum constants can be added, deleted, and reordered
without having to recompile the clients. If you removed an enum
that a client is using, you'll fail fast with an error message.

Now let's look at some advanced features.

Flavors of Declaration
Enums can be declared in various flavors. The enum FanState above is an
example of an inline declaration. These are useful for defining enums
have a limited scope - the use and throw type of enums. Since Java 5.0
introduces the keyword enum at the same level as class and interface
keywords, enums can be declared just as you would a new class or an
interface - in its own .java file (see Listing 5).

Normal rules of access visibility that apply to standalone Java classes
also apply to enums, whether they are declared inline or in a separate
file. For example, if you omitted the public keyword, the enum type
have the default package visibility and hence be accessible only within
package. Similarly if the SwitchState enum were to have a private
specifier, it wouldn't be accessible outside the class scope of Fan.
get the point.

As with other new features introduced in Java 5.0 such as generics,
have been used in several JDK packages. JDK 5.0 includes several enum
to support core classes. For instance, the newly introduced
java.lang.Thread class uses an enum named State to represent the
state of the thread. Some of the best enum candidates haven't been
converted over yet - like the most quoted Color class. You can use
as your field guide for spotting enums in Tigerland. The new API
conveniently lists all enums in the package-summary.html along with
top-level types. Once you have spotted them, go ahead and open the
code and see how the preachers practice. It's always fun.

Class-like Behavior
Since enums are class-like critters, they support most, if not all (see
Caveat Emptor sidebar), semantics supported by normal Java classes. The
enum type definition can have one or more parameterized constructors,
implement interfaces, and support class body elements such as
methods, instance and static initializer blocks, and even inner

In addition, arbitrary fields and methods can be added to individual
constants. Such constant-specific class bodies define anonymous classes
inside enum classes that extend the enclosing enum class. Listings 6-9
illustrate the use of some of these features.

There's a lot to digest here, so let's tackle them one at a time.

We are defining three types of accounts as enums - checking, savings,
investment. First things first - we need some clarification of
here. Every enum constant has a declaring class, which is also called
type. The term "enum type" is used to refer to the declaring class,
AccountType. When we use the term "enum constant", it's referring to
enlisted contents contained in the scope of AccountType, e.g.,
Savings, and Investment. It shouldn't be very confusing. Just think of
class declaration and its objects - the enum type is analogous to the
declaration and enum constants, the objects.

Enums Are Classes
Similarities between a normal class declaration and an enum declaration
hard to miss. The enum type AccountType implements the IAccountType
interface and has two constructors. What does it mean? To implement an
interface, the enum type must implement every method defined in the
interface. Since all enum constants are objects of the declared type,
share the common implementation of methods getAvgBalanceMethod and
getInterest- Rate. An enum constant declaration, when followed by
arguments, invokes the constructor defined by the enum type. In our
example, the enum constant Savings invokes the constructor

AccountType(double interestRate)

with argument 3.5.

All the standard rules of constructor overloading and selection
by the Java Language Specification are followed here. Since enum
Checking has no arguments following its declaration, it's necessary to
provide a no-arg default constructor. If the enum class has no
declarations, a parameterless default constructor is automatically
to match the implicit empty argument list.

Notice how an enum type can declare methods and attributes, again, just
like a normal Java class. For member type declaration, all rules of
scoping, access specifiers, and visibility are valid and therefore must
followed with regard to instance variables and methods. There is
rather interesting with the type AvgBalanceMethod. It's an enum within
enum. Since an enum type can support all types of class members, they
support enums too. Since AvgBalanceMethod is declared as public, it's
visible outside the scope of the enclosing AccountType. Notice how it's
accessed in the Account class.

Constant Class Bodies
Enum constants can be associated with an arbitrary class body often
referred to as a constant class body. Such classes are very similar to
anonymous class declarations (even named similarly) and are implicitly
static. This means they can access only static defined in the enclosing
scope. Since constant classes are implicit extensions of the enclosing
class, they can override methods defined in the enum type. In our
enum constant Investment overrides getAvgBalanceMethod defined by
AccountType. In fact, it would be perfectly legal to declare
AccountType as
abstract and force every enlisted enum constant to implement methods in
interface in their constant class body. A word of caution: although
for constant class bodies is a very powerful feature, it may be wise to
avoid stretching them because of the same reasons why excessive use of
anonymous classes is discouraged - they are less readable and hard to

It's important to mention here that only a nonfinal instance method in
java.lang.Enum is the toString() method. You can override and implement
per-constant toString() method to return a descriptive name for each
constant. The default implementation of toString() returns just the
equivalent of the constant. Therefore, as illustrated in the example,
may be a good idea to override when a more descriptive literal is

Before we proclaim victory, two new classes introduced for enum support
deserve consideration: java.util.EnumMap and java.util.EnumSet. As
names suggest, they are enum-enabled counterparts of the standard Java
collection implementation. They both require that each element
by the collection belong to one enum type. In short, they won't let you
and match enum constants from different types. It's rather interesting
they both retain the elements, e.g., the enum constants, in their
order, totally ignoring any custom implementation of the compareTo()
method. Be sure to check out their API documentation.

The new enums are a robust way to implement constant named lists and
them a compelling alternative to ad hoc enum implementations. With
class-like behavior and the ability to support arbitrary class members,
they are certainly bigger than they appear. Although you may not have
immediate need to use them in your projects, or at least not every
they offer, keep them in your toolbox and you'll soon find them handy.


Java 5.0 Release candidate home page:
JSR 201 - check out the enum draft spec:
JSR 176 - J2SE 5.0 Release contents:

Let the buyer beware: a simple axiom often used in commerce summarizes
well - it means the buyer alone is responsible for assessing the
quality of
a purchase before buying. Enums are so powerful, once you learn the
it's easy to be tempted to stretch and do "cool" things. Before you
it, bad things start happening.

Always check out the API spec and know the expected behavior before you
something to use. As a smart programmer, you also need to know the
limitations of the enums so that it can save your bacon some day.

1.  You can't new enums: Remember they are singletons. For the JVM to handle them properly, only one instance of each should exist. They are automatically created for you. Luckily the compiler catches explicit instantiation. For the same reason, enum constructors are implicitly private. Think about it.

2.  You can't extend enums: One enum cannot extend another one. You
extend the primordial java.lang.Enum either. That's how it works and if
are worried about this limitation, your design demands a second look.
shouldn't need a hierarchy of enums.

3.  You can't declare enums locally: Enum types cannot exist in any
lower than a class scope. You can't define them within a method.

4.  Order matters: Within the enum type class body, the constants must appear before other class elements such as attributes, methods, and constructors. This is true at least as of the 5.0 beta release.

5.  No nulls please: An enum constant cannot be null. It's that simple.

6.  Don't use ordinal: Code that uses an ordinal() method, e.g., logic
based on the position of an enum constant as it appears in the
must be discouraged. Your code will break at runtime if constants are
subsequently reordered. What's more, this is a runtime error. The
will not catch such a thing.

7.  Everything that sounds the same, isn't: There are a few other
in JDK 5.0 that sound very similar - Enumeration, EnumControl, to name
few. Don't assume they are enum implementations. Check the Javadoc.

8.  Spare the serialization: Enum serialization isn't like the normal
you have seen. The process by which enum constants are serialized
cannot be
customized. Any class-specific writeObject and writeReplace methods
by enum types are ignored during serialization. Similarly, any
serialPersistentFields or serialVersionUID field declarations are also
ignored - all enum types have a fixed serialVersionUID of 0L. Again,
shouldn't concern you too much. Let the language take care of the

December 12, 2004
Mark T wrote:

> After 8 years or so Java finally adds enums,

eeew, they just hacked it in using a Class...

Then again I guess that was always the proposed
solution to the lack of enums, so it makes sense

And if strings and arrays are Objects, then why
shouldn't enums be too ? (instead of primitives)

> I guess there is still hope for D
> adding a true boolean type in the future.

I wouldn't bet on it. Walter likes his arithmetic logic.

A boolean type does not make much sense until the
conditional and relational statements are changed ?

But it would be great if bool was made a proper keyword.


PS. There is still plenty of hope of D adding
    a non-zero bit type in the present... ;-)
Top | Discussion index | About this forum | D home